ContentProvider与ContentResolver

android 没有一个可以将所有应用程序数据统一放置的地方,即两个应用程序间的数据不能共享。但ContentProvider与ContentResolver可以解决多应用程序数据共享。

方法:

Demo1与Demo2:

1. Demo1 继承 ContentProvider类,实现里面的方法,主要包括:onCreate(),增删改查四个方法

代码:

public class MyContentProvider extends ContentProvider {

    /**

       *初始化时首先调用的方法

    **/
    @Override
    public boolean onCreate() {
        return false;
    }

 /**

   *  查询方法,对应参数:访问此ContentProvider的uri;所查询的列名,如果填null,则返回表中所有的数据;where语句;where语句的参数;排序

   **/

    @Override
    public Cursor query(Uri uri, String[] columns, String selection, String[] selectionArgs, String orderBy) {
        return null;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues contentValues) {
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
        return 0;
    }
}

需要在AndroidManifest中注册此ContentProvider: <provider android:name=".MyContentProvider" android:authorities="com.hui.demo" />

注: android:authorities="com.hui.demo" 这段代码是指定此ContentProvider的authorities,类似于activity中的IntentFilter中action的作用,说白了就是这个ContentProvider在一个android系统中的名字。ContentProvider在这个应用程序启动以后,就会永远存在android系统中,直到卸载这个应用程序。

2. 新建一个Sqlite数据库

public class MySqlite extends SQLiteOpenHelper {

    public static final String DB_NAME = "user_db";
    public static final int DB_VERSION = 1;

    public MySqlite(Context context){
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        String sql = "create table user(" +
                "id INTEGER PRIMARY KEY," +
                "name varchar(100)" +
                ")";
        sqLiteDatabase.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }

}

3. 在第一步中的MyContentProvider类中增加操作MySqlite数据库的代码,其实非常简单,就操作SQLiteDatabase类中的增删改查方法。

代码:

public class MyContentProvider extends ContentProvider {

    MySqlite mySqlite;
    SQLiteDatabase sqLiteDatabase;

    @Override
    public boolean onCreate() {
        mySqlite = new MySqlite(getContext());
        sqLiteDatabase = mySqlite.getWritableDatabase();
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] columns, String selection, String[] selectionArgs, String orderBy) {
        return sqLiteDatabase.query("user", columns, selection, selectionArgs, null, null, orderBy);

         //由于SQLiteDatabase的查询方法中多两个参数,是groupBy和having是分组的意思,用不到可以写为null即不分组。
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues contentValues) {
        sqLiteDatabase.insert("user", null, contentValues);
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        sqLiteDatabase.delete("user", selection, selectionArgs);
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
        sqLiteDatabase.update("user", contentValues, selection, selectionArgs);
        return 0;
    }

}

这样Demo1 中 ContentProvider就完成了。可以在MySqilte表中加入几条数据用于测试。

4. 在Demo2中 :得到ContentResolver类然后根据指定的uri和表名,操作Demo1中的ContentProvider。从而达到两个应用程序间数据共享的目的。

代码:

  ContentResolver contentResolver = getContentResolver();

  Uri uri = Uri.parse("content://com.hui.demo/user");

 //这里说一下:content://com.hui.demo/user      1.content://          我觉得是类似一个命令头一样的功能

                                                                  2.com.hui.demo     步骤1中的MyContentProvider的在AndroidManifest中注册时       

                                                                                              android:authorities=""属性。找到指定ContentProvider的作用

                         3.user                   表名

// 其实uri后面还可以有一项,比如说content://com.hui.demo/user/12   意思就是user表中id=12的记录。当然也可以在各个方法中selection和selectioArgs

// 即where语句中限制

//剩下就是非常简单的操作 contentResolver的增删改查的方法了。就列出简单的代码:

//            Cursor cursor = contentResolver.query(uri, null, null, null, null);
//            while (cursor.moveToNext()) {
//                int id = cursor.getInt(cursor.getColumnIndex("id"));
//                String name = cursor.getString(cursor.getColumnIndex("name"));
//                Log.e("demo4", "id is :" + id + ", name is;" + name);
//            }
//            contentResolver.insert()
//            contentResolver.update()
//            contentResolver.delete() 

UriMatcher

这里还有一个比较重要的类 UriMatcher类,此类的作用在于匹配访问 同一个ContentProvider 而不同表名的请求分发。假如Demo1中MySqilte类中数据库中初始化了两张不同的表,而Demo2又想分别操作这两张表,在Demo2中可以通过uri加入表名区分,而Demo1中在增删改查方法中uri字段还得取最后一块即表名用于区分来操作哪张表,非常麻烦。此时UriMatcher就派上了用场。

代码如下:

public class MyContentProvider extends ContentProvider {

    static UriMatcher uriMatcher;
    

    //用静态块初始化UriMatcher
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.hui.demo", "user", 1);        

        //参数意思: android:authorities="" 、表名、 唯一标识
        uriMatcher.addURI("com.hui.demo", "student", 2);
    }
    
    @Override
    public Cursor query(Uri uri, String[] columns, String selections, String[] argsSelections, String orderBy) {
        switch (uriMatcher.match(uri)){    //通过此UriMatcher.match(Uri uri)方法通过得到唯一标识,就知道要操作哪张表了。
            case 1:
                //This is user table
                break;
            case 2:
                //This is student table
                break;
        }
          }

 }

原文地址:https://www.cnblogs.com/lianghui66/p/2766663.html