浅析调用Android的content provider(2)

到这里,我们可以看到,PackageManagerService真的是用来管理手机的应用包的。通过它可以知道所有的系统可用资源。当然这些资源只是一些静态信息。通过这些信息,可以创建应用进程、初始化相关的Android组件。

应用进程的初始化       先看一下ActivityThread.main的实现,它创建了一个ActivityThread对象,初始化之后,进入消息循环。

public static final void main(String[] args) {       // ......        ActivityThread thread = new ActivityThread();       thread.attach(false);          Looper.loop();          // ......    }  

       attach函数中,回去调用ActivityManagerService.attachApplication方法。

mgr.attachApplication(mAppThread);  

       此时,会进入ActivityManagerService的进程空间,进入方法attachApplicationLocked,它会去获取和当前客户端应用程序关联的Provider信息。

List providers = generateApplicationProvidersLocked(app);  

       根据上面的信息,很容易知道此处是通过PackageManagerService获取Provider信息的。参数app表明,只是取运行在该app内的Provider。根据Android的文档,content provider必须在对应的AndroidManifest.xml中定义。默认情况下,是运行在安装包名称命名的进程里面。你也可以在android:process属性中制定所属的进程名称。另一个重要的属性android:multiprocess则可以指定provider的初始化方式,是分散在调用端进程中,从而避免进程间通信;还是只初始化在某个进程内,各个调用端只保留provider的代理。

随后,通过下面的方法调用,返回到应用程序的进程空间,参数中包含了上面获得的providers。此处的thread实际上就是应用端的ApplicationThread对象。

thread.bindApplication(processName, app.instrumentationInfo != null           ? app.instrumentationInfo : app.info, providers,           app.instrumentationClass, app.instrumentationProfileFile,           app.instrumentationArguments, app.instrumentationWatcher, testMode,            isRestrictedBackupMode, mConfiguration, getCommonServicesLocked());  

       ApplicationThread.bindApplication会发送BIND_APPLICATION消息给主线程。主线程会调用ActivityThread.handleBindApplication方法。这个函数里面主要分两步:一是根据需要创建Application、ApplicationContext和ApplicationContentResolver对象。因为,有可能多个apk���行在一个进程中,那么它们内部的组件(Component)执行的上下文(context)是不一样的。这几个对象实际上就是provider执行的上下文。二是根据传递过来的provider信息,创建provider实例,并保存在ActivityThread.mProviderMap中。具体的实例化provider过程如下(下面的代码位于ActivityThread.handleBindApplication中):

List<ProviderInfo> providers = data.providers;   if (providers != null) {       installContentProviders(app, providers);   }  

       获取ActivityManagerService传递过来的provider信息,并在本进程中初始化。具体的,installContentProviders方法中,会对每个provider调用installProvider方法:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzwsj.html