注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

Content Provider的加载  

2012-07-03 22:40:06|  分类: Android基础 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
在实际开发中,使用Content Provider(简称CP)有以下两种方式:
1)和应用在一个APK包里
这种情况下和应用在同一进程中。process name和uid都一样。
2)单独在一个APK包里。
这种情况下,如果在AndroidManifest.xml文件里声明了和某个进程同属一个进程,如:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"   
package="com.android.providers.telephony"
android:sharedUserId="android.uid.phone"
>
<application android:process="com.android.phone" 
android:allowClearUserData="false"
android:label="Dialer Storage"
android:icon="@drawable/ic_launcher_phone">
<provider android:name="TelephonyProvider" 
android:authorities="telephony" 
android:multiprocess="true" />

这个里面通过android:sharedUserId="android.uid.phone"android:process="com.android.phone"声明了该CP是和phone进程同属一个进程,拥有同样的process name和uid.
如果没有上述声明,那么该CP是在独立的进程中,拥有属于自己的process name和uid.
以上两种用法可以总结为:
1)CP和某个进程同属一个进程
这种情况下,当该进程启动时,会搜索属于该进程的所有CP,并加载。
2)CP属于独立的一个进程。

如果CP属于独立的一个进程,只有需要用到该CP时,才会去加载。
那么,当一个进程想要操作一个CP时,先需要获取该CP的对象,系统是这样处理的:
1)如果该CP属于当前主叫进程,因为在进程启动时就已经加载过了,所以系统会直接返回该CP的对象。
2)如果该CP不属于当前主叫进程,那么系统会进行相关处理(由ActivityManagerService进行,以下简称为AMS):
所有已加载的CP信息都已保存在AMS中。当需要获取某个CP的对象时,AMS会先判断该CP是否已被加载
如果已被加载,且该CP和当前主叫进程不属一个进程,但是该CP设置了multiprocess的属性(如上例中的android:multiprocess="true"),并且该CP属于系统级CP,那么就在当前主叫进程内部新生成该CP的对象。否则就需要通过IPC机制进行调用。
如果还未被加载,且该CP和当前主叫进程不属一个进程,但是该CP设置了multiprocess的属性(如上例中的android:multiprocess="true"),并且该CP属于系统级CP,那么就在当前主叫进程内部新生成该CP的对象。否则就需要先创建该CP所在的进程,然后再通过IPC机制进行调用。
Google文档android:multiprocess是这么描述的
android:multiprocess
Whether or not an instance of the content provider can be created in every client process — "true" if instances can run in multiple processes, and "false" if not. The default value is "false".

Normally, a content provider is instantiated in the process of the application that defined it. However, if this flag is set to "true", the system can create an instance in every process where there's a client that wants to interact with it, thus avoiding the overhead of interprocess communication.

但是这么描述时间是有误:
正确的描叙应该是这样的:当android:multiprocess=true 且 { 调用者与Provider的UID相同 或者 调用者UID为System_UID }  条件下,系统会在调用这个Provider的进程中创建Provider的实例,来避免进程间调用的开销。否则, 调用者只能通过进程间调用与Provider交互。
相关代码片段见ActivityManagerService.java的ContentProviderHolder getContentProviderImpl(IApplicationThread caller, String name)函数中

if (r != null && cpr.canRunHere(r)) {
                    // If this is a multiprocess provider, then just return its
                    // info and allow the caller to instantiate it.  Only do
                    // this if the provider is the same user as the caller's
                    // process, or can run as root (so can be in any process).
                    return cpr;
  }

结束!

  评论这张
 
阅读(722)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017