在学习了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条数据显示在界面上了,效果如下图所示:
![](https://static.assets-stash.eet-china.com/album/202109/02/150017we9blxu98b9oab5b.png)
ContentResolve应用中的数据
文章评论(0条评论)
登录后参与讨论