Contentprovider原理浅析

一、能知道什么?

      1,知道我们在调用ContentProvider的query后是怎么样处理流程?

      2,知道为什么Application为慢于ContentProvider初始化?

      3,理解stable和unstable的ContentProvider区别。

二、名词简写:

     CP   (ContentProvider)

     CPN(ContentProviderNative)

     CPP (ContentProviderProxy)

     CR   (ContentResolver)

     AT   (ActivityThread)

     AMS(ActivityMangerService)

 三、ContentProvider涉及的核心类: 

      CPN是一个典型的AIDL类(CPP就是我们AIDL经常看到远程调用的Proxy代理),当接收到请求会转入到CP的内部类Transport进行真正操作;在我们调用ContentResolver其实真正进行使用的还是ApplicationContentResolver。

四、ContentProvider流程:

      CP的流程分为两种:进程没有启动、进程启动了但是没有安装。(当然还有一种已经AMS缓存了就直接返回了)

      进程没有启动:

      进程启动了但是没有安装: 

       这里有个非常重要的函数就是:getContentProviderImp。

五、ContentProvider代码逻辑:

       当我们进入的时候其实会进入到475行这是我们接下来的核心,我们先看下假设能够获取   成功(475行返回不为NULL)的时候,我们可以看到490行使用的unstableProvider当进程死亡的时候会进入到498行调用stableProvider那么他们两个有什么区别呢?

       在4.1以前的我们使用的是stableProvider,它是当CP死亡的时候连带当前进程死亡;Google可能发现这样不好就是使用unstableProvider来规避这个,它是当CP死亡的时候连带当前进程不会死亡;我们其实并没有很好办法区分他们两个的。这也就解答了问题3了哦。我们继续探索从475行的函数:

       从475行的函数调用到1468处调用的就是ApplicationContentResolver的方法:

我们可以看到调用 2017行的函数(注意最后传入boolean变量,true就是stableProvider,反之就是你懂的)进入到AT内部。

       进入AT的方法acquireProvider方法,通过4778进入到AMS的方法:

       这里9820进入一个非常重要的函数getContentProviderImp这个函数是判断是否进程启动且安装、进程未启动和进程启动未安装:

     9493行通过Name获取缓存中CP(获取不为空就直接进入9516的if语句中):

       在上图中,这里有个函数值得注意一下就是canRunHere:

       9512行的providerRunning为false进入到: 

       在9702行进程判断没有其他进程正在启动的时候进入到9708。

       到这里我们可以区分出scheduleInstallProvider是进程启动未安装调用AT: 

       而startProcessLocked我们根据流程图(也可以参考Activity启动流程图)调用AT方法如下: 

       我们可以到4443是优先于4462这里也解答了(Application为慢于ContentProvider初始化)至于为什么这里会优先?我猜想是因为别的进程起来当前进程CP只需要数据所以需要尽快优先初始化。

       最终,这两个流程都会调用到installContentProviders;

在publishContentProviders会进行移除下图的启动列表和唤醒并告知安装已经完成。

       我们回到之前的ContentResolver因为475行不为空了(前面流程就是为了这个不行空),我们进行query操作(491行) 

       最后,进入到(通过CPN)Transport完成了query查询:

     这个就是所有的CP流程,留下一个问题:CP为什么需要放到AMS直接放到AT可以吗?

谢谢,有问题请及时与我沟通。

你可能感兴趣的:(Android)