Android面试——ContentProvider篇

参考链接:

https://blog.csdn.net/u011733869/article/details/83958712

http://gityuan.com/2016/07/30/content-provider/

https://blog.csdn.net/luoshengyang/article/details/6950440

 

 

注意点:

1. application初始化的时候会installProvider

2. 向AMS请求provider的时候如果对端进程不存在则请求的那个线程需要一直等待
当对方的进程启动之后并publish之后,请求provider的线程才可返回,所以尽量不要在主线程请求provider
3. 请求provider分为stable以及unsbale,stable类型链接在server进程挂掉之后,client进程会跟着被株连kill
4. insert/delete/update默认建立stable链接,query默认建立unstable链接,如果失败会重新建立stable链接
5. AMS作为一个中间管理员的身份,所有的provider会向它注册向AMS请求到provider之后,就可以在client和server之间自行binder通信,不需要再经过systemserver

 

 

 

 

 

一:什么是ContentProvider及其使用

ContentProvider通过Uri标识其他应用要访问的数据;

通过ContentResolver的增删改查方法实现对共享的数据的操作;

通过注册ContentObserver来监听数据是否发生了变化来对应的刷新页面

 

作用:为不同应用之间的数据共享提供统一的接口

二:内容提供者,内容解析者,内容观察者之间的关系

内容提供者:管理数据,提供数据的增删改查操作,数据源可以是数据库,文件,xml,网络等

内容解析者:外部进程通过内容解析者与内容提供者进行交互,

内容观察者:观察内容提供者的数据变化,并将变化通知给外界

 

三:ContentProvider的实现原理

1.ContentProvider的安装

当主线程收到H.BIND_APPLICATION消息后,会调用handleBindApplication方法。
handleBindApplication->installProvider(创建了provider对象)

创建ProviderClientRecord,这是一个provider在client进程中对应的对象,放入mProviderMap(记录所有contentProvider)

2. ContentResolver.query

调用端App在使用ContentProvider前首先要获取ContentProvider

  a.通过ContentResolver调用acquireProvider
  b.ActivityThread首先通过一个map查找是否已经install过这个Provider,如果install过就直接将之返回给调用者,如果没有install过就调用AMS的getContentProvider,AMS首先查找这个Provider是否被publish过,如果publish过就直接返回,否则通过PMS找到Provider所在的App。
  c.如果发现目标App进程未启动,就创建一个ContentProviderRecord对象然后调用其wait方法阻塞当前执行流程,启动目标App进程,AMS找到App的所有运行于当前进程的Provider,保存在map中,将要启动的所有Provider传给目标App进程,解除前面对获取Provider执行流程的阻塞.
  d.如果目标App进程已启动,AMS在getContentProvider里会查找到要获取的Provider,就直接返回了.调用端App收到AMS的返回结果后(acquireProvider返回),调用ActivityThread的installProvider将Provider记录到本地的一个map中,下次再调用acquireProvider就直接返回。ContentProvider所提供的接口中只有query是基于共享内存的,其他都是直接使用binder的入参出参进行数据传递。


AMS作为一个中间管理员的身份,所有的provider会向它注册
向AMS请求到provider之后,就可以在client和server之间自行binder通信,不需要再经过systemserver

 

三:ContentjProvider的优点

封装:解耦了底层数据的存储方式,提供了统一的接口来访问数据

跨进程:提供了数据更新通知机制;

 

四:URI是什么?

统一资源标识符

唯一标识Content Provider以及其中的数据

 

 

五:如何实现自己的ContentProvider

继承Content Provider;

实现几个方法:

onCreate:做初始化的工作

query

insert

update

delete:

getType:返回数据的MIME类型

 

posted @ 2022-02-27 12:33  向着内核前进!  阅读(247)  评论(0编辑  收藏  举报