Android高级应用开发(基础篇) - stage8 - 学习笔记

来源:互联网 发布:枢木朱雀知乎 编辑:程序博客网 时间:2024/05/17 07:51

ContentProvider


为什么要有ContentProvider?


之前的存储都是放在具体应用程序下面(具体的私有路径,限制访问权限),如果能够共享?

系统由于安全的因素,提供一些数据访问,不能直接开放给开发者,如何让开发者能够访问到这些数据?

如果我写好的数据库程序,希望封装并且提供一套公共标准,让外部调用而不直接操作我的数据库,如果实现?



ContentProvider是什么?


ContentProvider是一套存储访问数据的通道,让你无需了解下面的存储细节实现数据操作及共享

无论具体存储是如何的,存在哪儿的,但对外提供的模型是统一的


定义了ContentProvider对象,会在系统初始化的时候自动实例化(监听),无需我们手动去实例化对象

我们只需要通过ContentResolver去取和操作数据即可

ContentResolver与ContentProvider配对


特性:

ContentProvider是唯一的共享程序间数据方式,Android没有提供公共数据去让不同的程序去共享访问




其实ContentResolver与ContentProvider就像是C/S架构

首先要有网址,其次客户端发起请求,最后服务器端回复






需要再AndroidManifest.xml中配置ContentProvider

<provider android:authorities="com.example.transportationprovider" android:name=".provider.MyContentProvider" />


我们可以看到,配置的authorities就是URI中的authority的部分


定义服务器端

public class MyContentProvider extends ContentProvider{    @Override    public boolean onCreate() {        return false;    }    @Override    public Cursor query(Uri uri, String[] strings, String s, String[] strings2, String s2) {        if (uri.getAuthority().contains("com.example.transportationprovider"))        {            Log.i("log", "provider query");        }        return null;    }    @Override    public String getType(Uri uri) {        return null;    }    @Override    public Uri insert(Uri uri, ContentValues contentValues) {        if (uri.getAuthority().contains("com.example.transportationprovider"))        {            Log.i("log", "provider insert");        }        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;    }}


这些方法都是继承ContentProvider必须实现的



调用时

button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                ContentResolver _Resolver = getContentResolver();                Cursor _Cursor = _Resolver.query(Uri.parse("content://com.example.transportationprovider"), null, null, null, null);            }        });

这就相当于客户端发起的请求



以上就是一个很简单的ContentProvider相关的实现(里面啥都木有好伐……)

可以在自定义的ContentProvider中调用SQLiteDatabase进行相关的增删改查操作



一些系统提供的ContentProvider

·Browser:浏览器的书签,历史记录等

·CallLog:呼叫记录,包括呼入呼出

·ContactsContact:通讯录相关信息

·Calendar:日历相关信息

·MediaStore:媒体存储

·Settings:系统设置信息的部分内容

·UserDictionary:用户词典内容


调用通讯录的例子:




通过调用query,相当于是链接到了服务器端(的数据库)

startManagingCursor接收查询到结果的Cursor,对其进行管理和监视

当Activity消亡不再使用时就会销毁Cursor的链接,使其不再保持链接(重要)






如果发现别的进程无法调用提供的ContentProvider,那可能是因为没有对外提供

将定义的provider中加入android:multiprocess="true"就能在不同进程间访问了




总结:

1、定义Provider

(1)写一个类继承ContentProvider

(2)实现ContentProvider的方法

(3)注册到manifest中,进程间提供加入multiprocess属性

2、使用ContentResolver调用ContentProvider中的内容(代理模式,使用Binder)




ContentProvider的机制

当程序安装/卸载时,Provider将会注册/删除到ProviderManager中,相当于有一个链表,

使用ContentResolver访问时,会到ProviderManager中寻找,并启动相关Provider

所以Provider不是由主Activity启动的



ContentProvider调用的时候宿主进程生命周期

接收调用的时候启动宿主进程,操作完毕后,宿主进程为empty

0 0
原创粉丝点击