在学习了ContentProvider 的几个常用类和如何创建一个内容提供者的方法之后,下面我们用一个实例来进一步加深理解。通过一个完整的实例来展示如何用ContentProvider类进行数据库操作。将通过创建 100条模拟数据,用ListView 展示出来。
在进行具体的数据库操作之前,先建立一个Java 实体类 User类,再通过这个实体类进行数据的封装。User类中包括 userId、name、age三个属性,具体代码如下∶
- package com.rfstar.sqlitetest2;
- public class User {
- private int userId;
- private String name;
- private int age;
- public int getUserId()
- {
- return userId;
- }
- public void setUserId(int userId)
- {
- this.userId=userId;
- }
- public String getName()
- {
- return name;
- }
- public void setName(String name)
- {
- this.name=name;
- }
- public int getAge()
- {
- return age;
- }
- public void setAge(int age)
- {
- this.age=age;
- }
- }
完成Java实体类的创建之后,通过继承SQLiteOpenHelper来实现数据库辅助类,并实现其中的onCeate()方法和onUpgrate()方法。在onCreate()方法中创建表并使表中的字段与User类的属性相一致。同时实现onUpgrate()方法,以更新数据库。
- package com.rfstar.sqlitetest2;
- import android.content.Context;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- public class OpenHelper extends SQLiteOpenHelper {
- private static final String name="test.db";
- private static final int version=1;
- public OpenHelper(Context context)
- {
- super(context,name,null,version);
- }
- @Override
- public void onCreate(SQLiteDatabase sqLiteDatabase) {
- sqLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS "+
- "user (person_id INTEGER PRIMARY KEY AUTOINCREMENT,"+
- "name varchar(32),age INTEGER)");
- }
- @Override
- public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
- if(newVersion>oldVersion)
- {
- sqLiteDatabase.execSQL("ALTER TABLE user ADD phone VARCHAR(11)");
- }
- }
- }
接下来创建UserDao类,并在该类中实现对User的增、删、改、查操作,代码如下:
- package com.rfstar.sqlitetest2;
- import android.content.ContentValues;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import java.util.ArrayList;
- import java.util.List;
- public class UserDao {
- private SQLiteDatabase database;
- public UserDao(SQLiteDatabase sqLiteDatabase) {
- this.database = sqLiteDatabase;
- }
- public boolean insert(User user) {
- ContentValues contentValues = new ContentValues();
- contentValues.put("name", user.getName());
- contentValues.put("age", user.getAge());
- long insertResult = database.insert("user", null, contentValues);
- if (insertResult == -1) {
- return false;
- }
- return true;
- }
- public boolean delete(User user) {
- int deleteResult = database.delete("user", "user_id+?", new String[]{user.getUserId() + ""});
- if (deleteResult == 0){
- return false;
- }
- return true;
- }
- public boolean update(User user)
- {
- ContentValues contentValues=new ContentValues();
- contentValues.put("name",user.getName());
- contentValues.put("age",user.getAge());
- int updateResult=database.update("user",contentValues,"user_id=?",new String[]{user.getUserId()+""});
- if(updateResult==0)
- {
- return false;
- }
- return true;
- }
- public User queryOne(User user)
- {
- Cursor cursor=database.query("user",null,"name=?",new String[]
- {user.getName()},null,null,null);
- while (cursor.moveToNext())
- {
- user.setUserId(cursor.getInt(0));
- user.setAge(cursor.getInt(2));
- }
- return user;
- }
- public List<User> queryAll()
- {
- List<User> userList=new ArrayList<>();
- Cursor cursor=database.query("user",null,null,null,null,null,null);
- while (cursor.moveToNext())
- {
- User user=new User();
- user.setUserId(cursor.getInt(0));
- user.setName(cursor.getString(1));
- user.setAge(cursor.getInt(2));
- userList.add(user);
- }
- return userList;
- }
- }
当完成上述3个类之后,接下来就可以使用Activity进行各项操作了(1)创建数据
创建一个MainActivity,并在MainActivity中创建一个循环生成100条数据的方法,代码如下:
- package com.rfstar.sqlitetest2;
- import androidx.appcompat.app.AppCompatActivity;
- import android.database.sqlite.SQLiteDatabase;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.ListView;
- import android.widget.SimpleAdapter;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class MainActivity extends AppCompatActivity {
- private OpenHelper openHelper;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- openHelper=new OpenHelper(this);
- initData();
- }
- private void initData()
- {
- SQLiteDatabase sqLiteDatabase=openHelper.getReadableDatabase();
- UserDao userDao=new UserDao(sqLiteDatabase);
- sqLiteDatabase.beginTransaction();
- try
- {
- User user=new User();
- for(int i=0;i<100;i++)
- {
- user.setName("大鸟科创空间"+i);
- user.setAge(6);
- userDao.insert(user);
- }
- sqLiteDatabase.setTransactionSuccessful();
- }catch (Exception e)
- {
- Log.e("user Transaction",e.toString());
- }finally {
- sqLiteDatabase.endTransaction();
- sqLiteDatabase.close();
- }
- }
- }
我们在这个应用中增加一个ContentProvider,再创建一个新的应用,在应用中去操作这个ContentProvider的数据。
首先创建UserProvider类,并让UserProvider类继承ContentProvider类,并实现onCreate()等方法。这些方法主要是对数据库进行操作,代码如下:
- package com.rfstar.sqlitetest;
- import android.content.ContentProvider;
- import android.content.ContentUris;
- import android.content.ContentValues;
- import android.content.UriMatcher;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import android.net.Uri;
- import java.util.regex.Matcher;
- public class UserProvider extends ContentProvider {
- private OpenHelper openHelper;
- //若不匹配采用UriMatcher.NO_MATCH(-1)返回
- private static final UriMatcher MATCHER=new UriMatcher(UriMatcher.NO_MATCH);
- //匹配码
- private static final int USER=1;
- private static final int USER_ID=2;
- static
- {
- //匹配返回USER,不匹配返回-1
- MATCHER.addURI("com.rfstar.sqlitetest.userProvider","user",USER);
- //匹配返回USER_ID,不匹配返回-1
- MATCHER.addURI("com.rfstar.sqlitetest.userProvider","user/#",USER_ID);
- }
- @Override
- public boolean onCreate()
- {
- openHelper=new OpenHelper(this.getContext());
- return true;
- }
- /**
- * 外部应用向本应用插入数据
- */
- @Override
- public Uri insert(Uri uri, ContentValues values)
- {
- SQLiteDatabase db=openHelper.getWritableDatabase();
- switch (MATCHER.match(uri))
- {
- case USER:
- long id=db.insert("user","name",values);
- Uri insertUri= ContentUris.withAppendedId(uri,id);
- return insertUri;
- default:
- throw new IllegalArgumentException("this is unknown uri:"+uri);
- }
- }
- /**
- * 外部应用向本应用删除数据
- */
- @Override
- public int delete(Uri uri,String selection,String[] selectionArgs)
- {
- SQLiteDatabase db=openHelper.getWritableDatabase();
- switch (MATCHER.match(uri))
- {
- case USER:
- return db.delete("user",selection,selectionArgs);//删除所有记录
- case USER_ID:
- long id=ContentUris.parseId(uri);//取得跟在Uri后面的数字
- String where="user_id="+id;
- if(null!=selection&&!"".equals(selection.trim()))
- {
- where+="and"+selection;
- }
- return db.delete("user",where,selectionArgs);
- default:
- throw new IllegalArgumentException("this is unknown uri:"+uri);
- }
- }
- /**
- * 外部应用向本应用更新数据
- */
- @Override
- public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs)
- {
- SQLiteDatabase db=openHelper.getWritableDatabase();
- switch (MATCHER.match(uri))
- {
- case USER:
- return db.update("user",values,selection,selectionArgs);//更新所有记录
- case USER_ID:
- long id=ContentUris.parseId(uri);//取得跟在Uri后面的数字
- String where="user_id="+id;
- if(null!=selection&&!"".equals(selection.trim()))
- {
- where+="and"+selection;
- }
- return db.update("user",values,where,selectionArgs);
- default:
- throw new IllegalArgumentException("this is unknown uri:"+uri);
- }
- }
- /**
- * 如果是单条记录,应该返回以vnd.android.cursor.item/为首的字符串
- * 如果是多条记录,应该返回以vnd.android.cursor.dir/为首的字符串
- */
- @Override
- public String getType(Uri uri)
- {
- switch(MATCHER.match(uri))
- {
- case USER:
- return "vnd.android.cursor.dir/user";
- case USER_ID:
- return "vnd.android.cursor.item/user";
- default:
- throw new IllegalArgumentException("this is unknown uri:"+uri);
- }
- }
- @Override
- public Cursor query(Uri uri,String[] projection,String selection,String[]selectionArgs,String sortOrder)
- {
- SQLiteDatabase db=openHelper.getReadableDatabase();
- switch (MATCHER.match(uri))
- {
- case USER:
- return db.query("user",projection,selection,selectionArgs,null,null,sortOrder);
- case USER_ID:
- long id=ContentUris.parseId(uri);
- String where="user_id="+id;
- if(null!=selection&&!"".equals(selection.trim()))
- {
- where+="and"+selection;
- }
- return db.query("user",projection,where,selectionArgs,null,null,sortOrder);
- default:
- throw new IllegalArgumentException("this is unknown uri:"+uri);
- }
- }
- }
代码编写完成后,需要在AndroidManifest.xml文件中进行配置。在Application节点下面增加一条配置:
- <provider
- android:name="com.rfstar.sqlitetest.UserProvider"
- android:authorities="com.rfstar.sqlitetest.userProvider"
- android:exported="true"
- android:multiprocess="true"/>
此时运行应用在手机上,100条数据就创建成功了。但是,此时它已经不是一个简单的应用了,而是变成了一个内容提供者。
创建一个新的应用,在此类中使用ContentResolver来获取ContentProvider中的数据,并通过ListView展示出来。
(2)展示数据
在上一部分创建了100条数据的基础上,用ListView来展现这些数据。这需要修改Acticity的布局文件,并创建一个item布局文件,同时在Activity中查询数据。由于数据中只有name和 age两个文本,因此选择 SimpleAdapter 作为 ListView 的适配器。
在布局文件中加入一个ListView控件:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
- <ListView
- android:id="@+id/user_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- </RelativeLayout>
为了能够展示出数据中的name和age两个字段,我们创建一个item:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:id="@+id/user_name"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:layout_gravity="center"
- android:textSize="20dp"/>
- <TextView
- android:id="@+id/user_age"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center_vertical"
- android:textSize="20dp"/>
- </LinearLayout>
完成了这几个步骤之后,就可以在MainActivity中查询数据库并使用适配器展示到ListView中了。此时使用ContentResolver来获取ContentProvider中的数据:
- package com.rfstar.sqlitetest31;
- import androidx.appcompat.app.AppCompatActivity;
- import android.database.sqlite.SQLiteDatabase;
- import android.os.Bundle;
- import android.widget.ListView;
- import android.widget.SimpleAdapter;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class MainActivity extends AppCompatActivity {
- private ListView listView;
- private List<Map<String,Object>> mapList;
- private OpenHelper openHelper;
- private List<User> userList;
- private UserResolve userResolve;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initData();
- initView();
- }
- private void initView()
- {
- listView=(ListView)findViewById(R.id.user_list);
- final SimpleAdapter simpleAdapter=new SimpleAdapter(
- this,mapList,R.layout.item,
- new String[]{"name","age"},new int[]{R.id.user_name,R.id.user_age});
- listView.setAdapter(simpleAdapter);
- }
- private void initData() {
- userResolve=new UserResolve(this);
- userList=userResolve.query();
- mapList=new ArrayList<>();
- for(User user:userList)
- {
- Map<String,Object> map=new HashMap<>();
- map.put("name",user.getName());
- map.put("age",user.getAge());
- mapList.add(map);
- }
- }
- }
运行程序,就会发现创建数据时添加的100条数据显示在界面上了,效果如下图所示:
ContentResolve应用中的数据
文章评论(0条评论)
登录后参与讨论