zoukankan      html  css  js  c++  java
  • 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;
            }
              }

     }

  • 相关阅读:
    js-异步机制与同步机制
    js-正则表达式
    js-注释代码习惯
    布局-块级元素水平垂直居中
    js-本地调试跨域
    vue2-项目资源收集
    git 忽略文件夹
    运行npm run eject报错解决方法
    柯里化函数
    常用正则表达式总结
  • 原文地址:https://www.cnblogs.com/lianghui66/p/2766663.html
Copyright © 2011-2022 走看看