• ContentProvider和ContentResolver的使用


    ContentProvider

    ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。
    ContentProvider的就是自定义增删改查接口并暴露出去,让别的应用访问自己的数据。ContentResolver就是按照一定规则访问内容提供者的数据。

    ContentProvider对外共享数据步骤:

    步骤

    1. 定义一个类 继承 ContentProvider
    2. 定义匹配规则 uri
    3. 通过静态代码块添加匹配规则 
    4.在manifest.xml中配置contentProvider.  

    Uri介绍

    uri代表了要操作的数据

    上面我们提到了Android提供内容的叫Provider,那么在Android中怎么区分各个Provider?

    Uri作为唯一的标识来标识这个Provider。

    ContentProvider的scheme为:content://
    Authority 用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
    路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
    要操作file表中id为10的记录,可以构建这样的路径:/file/10
    要操作file表中id为10的记录的name字段, file/10/name
    要操作file表中的所有记录,可以构建这样的路径:/file

    当然要操作的数据可以是数据库,也可以是文件、xml或网络等其他存储方式。

    代码示例

    public class FileProvider  extends ContentProvider {
    
        private Context mContext;
        private static final int QUEYSUCESS = 0;
        private static final int INSERTSUCESS = 1;
        //UriMatcher.NO_MATCH表示不匹配任何路径的返回码
        private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    
        private SQLiteDatabase mDb;
        private String mTableName = DbOpenHelper.STUDENT_TABLE_NAME;
        static{
            //注册所有要匹配的uri
            mUriMatcher.addURI("com.itcast.contentp.FileProvider", "query", QUEYSUCESS);
            mUriMatcher.addURI("com.itcast.contentp.FileProvider", "insert", INSERTSUCESS);
        }
    
        //该方法在其它应用第一次访问它时才会被创建
        @Override
        public boolean onCreate() {        
            mContext = getContext();
            mDb = new DbOpenHelper(mContext).getWritableDatabase();
            return false;
        }
    
        /**
        *public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, String sortOrder)
        *projection : 这个参数告诉查询要返回的列(Column)即需要的字段,比如Contacts Provider提供了联系人的ID和联系人的NAME等内容.
        *selection :查询where字句
        *selectionArgs : 查询条件属性值
        *sortOrder :结果排序
        */
        @Override
        public Cursor query(Uri uri, String[] arg1, String arg2, String[] arg3,String arg4) {
            if (mUriMatcher.match(uri)== QUEYSUCESS ) {//uri匹配后进行下面的操作
                Cursor cursor = mDb.query(tableName, arg1, arg2, arg3, null, null, null);
                getContext().getContentResolver().notifyChange(uri, null);
                return cursor;
            }else{
                throw new IllegalArgumentException("match fail");
            }
    }
    这里只给出部分代码。。。。。。


    ContentResolver

    使用ContentResolver调用ContentProvider提供的接口,对ContentProvider中的数据进行添加、删除、修改和查询操作时。

    可以使用Activity提供的getContentResolver()方法来获取ContentResolver对象。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:

    • public Uri insert(Uri uri, ContentValues values)
    • public int delete(Uri uri, String selection, String[] selectionArgs)。
    • public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
    • public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)


    1.对ContentProvider中的数据进行增删改查

    直接看代码:

    //uriQuery必须与要查询的ContentProvider中的要操作数据的uri保持一致(btw 这里只给了查询好插入的例子)

    ContentValues values = new ContentValues();
    Cursor cursor = getContentResolver().query(uriQuery, null, null, null, null);
    int count = cursor.getCount(); //获取到一共有多少行
    int contact_id = count + 1;
    
    ContentValues nameValues = new ContentValues();
    nameValues.put("name", name);
    nameValues.put("mime_type", "vnd.android.cursor.item/name");
    nameValues.put("contact_id", contact_id);
    getContentResolver().insert(uriInsert, nameValues);

    2.监听ContentProvider中数据的变化

    在ContentProvider 发生数据变化时调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者。

    当数据放生变化时会调用ContentObserver的onChange()来进行一系列的后续操作~~~

    如下: 

    public class MainActivity extends Activity {
    
        private Uri uri;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            //注册
            uri = Uri.parse("content://com.example.contentp.AccountProvider"); 
            getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler())) 
    }
    }

    //监听到变化后调用onChange()来执行一系列操作

    private class MyObserver extends ContentObserver {
        Uri uri = Uri.parse("content://com.example.contentp.AccountProvider"); 

    public MyObserver(Handler handler) {

    super(handler);
    }
    @Override
    public void onChange(boolean selfChange) {
    Cursor cursor = getContentResolver().query(uri, new String[]{"file","mime_type","date"}, null, null, null);
    while(cursor.moveToNext()){
    //执行一些操作
    }
    }
    }

    ContentProviderClient 

    与ContentResolver一样都是用来对ContentProvider中的数据进行添加、删除、修改和查询操作的

    通过调用 getContentResolver().acquireContentProviderClient(authority) 方法获取 ContentProviderClient对象。

    用法跟ContentResolver相似,不同点是ContentProviderClient 对象必须在结束使用后,调用ContentProviderClient.release()来释放。这会是系统释放对应的ContentProvider对象。

    对于相同ContentProvider 的多次调用,推荐使用ContentProviderClient。

  • 相关阅读:
    2019年2月8日训练日记(文件操作知识点小结)
    2019年2月7日训练日记
    2019年2月6日训练日记
    2019年2月5日训练日记
    2019年2月4日训练日记(递归学习小结)
    【Java】Java中的IO流
    【Java】Java中线程的使用
    【Java】Java图形化用户界面-GUI
    【Java】Java中的集合类
    C++程序学习之实现手机通讯录功能模拟
  • 原文地址:https://www.cnblogs.com/lilykeke/p/10329964.html
Copyright © 2020-2023  润新知