ContentProvider#onCreate的调用时机
Application#attachBaseContext()
-> ContentProvide#onCreate()
-> Application#onCreate()
ActivityThread#handleBindApplication

- LoadedApk#makeApplication方法内部会调用Instrumentation#newApplication方法;Instrumentation#newApplication方法内部会调用到Application#attach方法最终调用到Application#attachbasecontext方法。
- ActivityThread#installContentProviders方法最终会调用到ContentProvider#onCreate方法
ContentProvider的onCreate和CRUD运行在哪个线程?它们是线程安全的吗?
- ContentProvider的底层是Binder,当跨进程访问ContentProvider的时候,CRUD运行在Binder线程池中,不是线程安全的,而如果在同一个进程访问ContentProvider,根据Binder的原理,同进程的Binder调用就是直接的对象调用,这个时候CRUD运行在调用者的线程中。
- ContentProvider的内部存储不一定是sqlite,它可以是任意数据。
- Contentprovider的CRUD是阻塞调用
Context.getContentResolver#query的流程
1、ContextImpl.getContentResolver()返回的是ApplicationContentResolver
2、ActivityThread.acquireProvider()首先检查是否已经存在目标ContentProvider,如果有就直接返回它,如果没有则请求AMS启动。
3、ActivityManagerService的getContentProviderImpl方法干了很多事情,我们看重点,如果process已经启动了则proc.thread.scheduleInstallProvider(cpi),否则proc = startProcessLocked(),这里我们看后面一种情况。
4、ActivityManagerService.startProcessLocked完成新进程的启动。然后走到ActivityThread.main()
5、ActivityThread.handleBindApplication()主要工作:
5.1、创建ContentImpl
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
5.2、创建Instrumentation
mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance();
mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
5.3、创建Application对象
app = data.info.makeApplication(data.restrictedBackupMode, null );
5.4、启动当前进程的ContentProvider
installContentProviders(app, data.providers)
5.4.1 installProvider方法反射实例化ContentProvider对象,同时也实例化了ContentProvider的成员变量mTransport。
class Transport extends ContentProviderNative
-
class ContentProviderNative extends Binder implements IContentProvider 5.4.2 ActivityManager.getService().publishContentProviders(getApplicationThread(), results)上报ContentProviderHolder给Ams
5.5、调用Application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);
6、总结一下就是其他应用通过AMS获取ContentProvider的Binder对象即IContentProvider,IContentProvider的具体实现是ContentProviderNative和ContentProvider.Transport,调用IContentProvider的query方法最终会以进程间通信的方式调用到ContentProvider.Transport的query方法,最终调用了ContentProvider的query方法,结果再通过Binder返回给调用者。
网友评论