美文网首页四大组件
Android--ContentProvider

Android--ContentProvider

作者: 始終上路过 | 来源:发表于2019-08-13 21:19 被阅读0次

    概述:

    ContentProvider可以理解为一个Android应用对外开放的接口,只要是符合它所定义的Uri格式的请求,均可以正常访问执行操作。其他的Android应用可以使用ContentResolver对象通过与ContentProvider同名的方法请求执行,被执行的就是ContentProvider中的同名方法。所以ContentProvider很多对外可以访问的方法,在ContentResolver中均有同名的方法,是一一对应的。


    原理图

    Uri:

    在Android中,Uri是一种比较常见的资源访问方式。而对于ContentProvider而言,Uri也是有固定格式的:

    <srandard_prefix>://<authority>/<data_path>/<id>
    <srandard_prefix>:ContentProvider的srandard_prefix始终是content://。
    <authority>:ContentProvider的名称。
    <data_path>:请求的数据类型。
    <id>:指定请求的特定数据。
    

    ContentProvider

    ContentProvider也是Android应用的四大组件之一,所以也需要在AndroidManifest.xml文件中进行配置。而且某个应用程序通过ContentProvider暴露了自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过这个接口来操作它的内部数据。

    Android附带了许多有用的ContentProvider,但是本篇博客不会涉及到这些内容的,以后有时间会再讲解。Android附带的ContentProvider包括:
    • Browser:存储如浏览器的信息。
    • CallLog:存储通话记录等信息。
    • Contacts:存储联系人等信息。
    • MediaStore:存储媒体文件的信息。
    • Settings:存储设备的设置和首选项信息。

    在Android中,如果要创建自己的内容提供者的时候,需要扩展抽象类ContentProvider,并重写其中定义的各种方法。然后在AndroidManifest.xml文件中注册该ContentProvider即可。

    ContentProvider是内容提供者,实现Android应用之间的数据交互,对于数据操作,无非也就是CRUD而已。下面是ContentProvider必须要实现的几个方法:

    • onCreate():初始化提供者。
    • query(Uri, String[], String, String[], String):查询数据,返回一个数据Cursor对象。
    • insert(Uri, ContentValues):插入一条数据。
    • update(Uri, ContentValues, String, String[]):根据条件更新数据。
    • delete(Uri, String, String[]):根据条件删除数据。
    • getType(Uri) 返回MIME类型对应内容的URI。

    除了onCreate()和getType()方法外,其他的均为CRUD操作,这些方法中,Uri参数为与ContentProvider匹配的请求Uri。
      Tips:还有两个非常有意思的方法,必须要提一下,call()和bulkInsert()方法,使用call,理论上可以在ContentResolver中执行ContentProvider暴露出来的任何方法,而bulkInsert()方法用于插入多条数据。

    在ContentProvider的CRUD操作,均会传递一个Uri对象,通过这个对象来匹配对应的请求。那么如何确定一个Uri执行哪项操作呢?需要用到一个UriMatcher对象,这个对象用来帮助内容提供者匹配Uri。它所提供的方法非常简单,仅有两个:

    • void addURI(String authority,String path,int code):添加一个Uri匹配项,authority为AndroidManifest.xml中注册的ContentProvider中的authority属性;path为一个路径,可以设置通配符,#表示任意数字,*表示任意字符;code为自定义的一个Uri代码。
    • int match(Uri uri):匹配传递的Uri,返回addURI()传递的code参数。

    在创建好一个ContentProvider之后,还需要在AndroidManifest.xml文件中对ContentProvider进行配置,使用一个<provider.../>节点,一般只需要设置两个属性即可访问,一些额外的属性就是为了设置访问权限而存在的

    • android:name:provider的响应类。
    • android:authorities:Provider的唯一标识,用于Uri匹配,一般为ContentProvider类的全名。

    ContentResolver

    ContentResolver,内容访问者。可以通过ContentResolver来操作ContentProvider所暴露处理的接口。一般使用Content.getContentResolver()方法获取ContentResolver对象。上面已经提到ContentResolver的很多方法与ContentProvider一一对应,所以它也存在insert、query、update、delete等方法。

    自定义ContentProvider

    一、什么是自定义内容提供者

    谈到内容提供者,大家就应该想到提供方和索要方,现在,我们想要做提供方,别人来访问我们的数据库,那我们就需要自定义内容提供者了。

    二.思路:

    1.提供方:ContentProvider
    (1)创建数据库,自定义类继承SQLiteOpenHelper
    (2)自定义内容提供者类,继承ContentProvider,重写insert/delete/update/query方法,向外界提供方法
    (3)清单文件中注册内容提供者

    2.索要方:ContentResolver
    (1)通过Context的getContentResolver方法获得ContentResolver对象
    (2)确定uri
    (3)调用insert/delete/update/query方法访问数据库

    自定义类继承SQLiteOpenHelper

    public class MySqlHelper extends SQLiteOpenHelper {
        public MySqlHelper(Context context) {
            super(context, "user.db",null,1);
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            sqLiteDatabase.execSQL("create table student (_id integer primary key autoincrement ,name varchar(20),age integer)");
            for (int i = 0; i < 5; i++) {
                sqLiteDatabase.execSQL("insert into student values(null,?,?)",new String[]{"弟弟"+i,i+""});
            }
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    
        }
    }
    

    自定义内容提供者类,继承ContentProvider
    重新其他的方法

    public class MyContentProvider extends ContentProvider {
        private MySqlHelper mySqlHelper;
        private SQLiteDatabase db;
    
        @Override
        public boolean onCreate() {
            mySqlHelper = new MySqlHelper(getContext());
            db = mySqlHelper.getReadableDatabase();
            if (db != null){
                return true;
            }
            return false;
        }
    
        @Override
        public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
            Cursor cursor = db.query("student", strings, s, strings1, null, null, s1);
            return cursor;
        }
    
        @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 s, String[] strings) {
            return 0;
        }
    
        @Override
        public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
            return 0;
        }
    }
    

    清单文件中注册内容提供者

    内容索要方
    (1)获取ContentResolver直接获取

    进程间数据共享

    进程间ContentProvider增删改查

    自定义权限

    1.使用场景
    定义权限一般用于暴露出去的组件,提高安全性。Android允许一个应用(客户端)调用另一个应用(服务端)的组件。那么作为服务端的应用就得暴露相应的组件,客户端应用才能访问。当然,在暴露的时候,权限是非必须的,如果暴露的组件没有权限的话,那么任何的其他应用都可以来调用该组件;如果该组件申请了权限,那么只有拥有该权限的应用才能调用该组件。

    相关文章

      网友评论

        本文标题:Android--ContentProvider

        本文链接:https://www.haomeiwen.com/subject/gylijctx.html