ContentProvider实现IPC

来源:互联网 发布:中国公知和精英的溃败 编辑:程序博客网 时间:2024/05/17 06:53

ContentProvider作为专门为不同的应用之间进行数据共享的组件。IPC简直就是它的专业。

1,ContentProvider可以用来做什么
ContentProvider提供了访问本地应用程序的数据库的办法,它对外提供了几个接口,让想获得这些数据的其他应用程序去实现。
而如果没有ContentProvider,试想下怎么获取这些数据,不同的应用处于不同的进程,我们自己去操作的话,往往会很复杂。而android系统很贴心,为我们提供了ContentProvider。

获取什么数据呢。比如:手机里视频,音频,通讯录,图片等。

2,一个ContentProvider例子
实现目标:通过ContentProvider访问本地我自己创建的数据库。

继承ContentProvider,创建自己的内容提供者
xml文件中注册provider

    <provider        android:exported="true"//true表示允许不同进程的组件访问        android:authorities="asule.myhope.MyContentProvider"        android:name=".MyContentProvider"/>

要知道的是每一个ContentProvider都会为自己的数据集提供一个唯一的Uri。
Uri的组成:标准前缀+authorities的值+path
标准前缀:content://,前缀永远是这个,无法改变
authorities:唯一标识provider,为了唯一,通常写为“包名+类名”
path:自己定义的路径

继承ContentProvider,会复写几个抽象方法。

onCreate不必多说,第一次使用provider时就会调用。getType,返回的是一个Uri请求所对应的MIME类型。一般都不关注这个方法,返回null即可。还有就是CRUD,增删改查的四个方法。

定义一个Uri匹配器,并为这个匹配器添加一些规则。

    //匹配器    private static UriMatcher mather=new UriMatcher(UriMatcher.NO_MATCH);    private static String authorities="asule.myhope.MyContentProvider";    //添加一组规则    static{        mather.addURI(authorities,"insert",0);    }
public Cursor query(Uri uri, String[] projection, String selection,                     String[] selectionArgs, String sortOrder) {        if(mather.match(uri)==0){            SQLiteDatabase db=sqlLite.getReadableDatabase();            Cursor cursor=                        db.query("asule",projection,selection,selectionArgs,null,null,sortOrder);            return cursor;        }        return null;    }

为匹配器添加规则(addURI)后,在query查询方法中,需要对传入的匹配器进行判断。匹配成功,就会把我们创建的数据库的游标返回。
(只要应用中注册了内容提供者,应用一旦启动,该内容提供者就会被创建),会打印下面的句子:

ActivityThread: Pub asule.myhope.MyContentProvider: asule.myhope.MyContentProvider

而在另一个应用里:

        ContentResolver contentResolver=getContentResolver();        Uri uri=Uri.parse("content://asule.myhope.MyContentProvider/insert");        Cursor cursor=contentResolver.query(uri, null, null, null, null);        while (cursor.moveToNext()){            String name=cursor.getString(cursor.getColumnIndex("name"));            String phone=cursor.getString(cursor.getColumnIndex("phone"));            System.out.println("name:"+name+"phone:"+phone);        }

ContentResolver可以理解为一种代理(),无论是访问手机里的各种数据,还是访问前面所说的自己创建的数据库。真实对象的实现原则肯定是一样的,只是不知道你的数据集的Uri是什么。

contentResolver.query(uri, null, null, null, null);就会调用ContentProvider的query。uri和匹配规则可以匹配,就会暴露出数据库的真面目。返回Cursor后,我们就可以在另一个应用(进程)里获得数据库的数据。这样就通过ContentProvider实现了数据共享。

ContentProvider中有CRUD等方法,也可以认为ContentProvider的底层结构其实是SQLite数据库。但是别忘了,通过ContentProvider也可以访问视频,音频,文件。而这些也表明ContentProvider还支持文件数据。
那怎么通过ContentProvider访问文件数据?
还是一个原则,如果Uri匹配,我们可以把文件数据的引用返回给外界。
android系统的MediaStore功能就是文件系统的ContentProvider。

0 0
原创粉丝点击