美文网首页
ContentProvider要点

ContentProvider要点

作者: taoyyyy | 来源:发表于2020-10-13 21:10 被阅读0次

ContentProvider#onCreate的调用时机

Application#attachBaseContext()
-> ContentProvide#onCreate()
-> Application#onCreate()

ActivityThread#handleBindApplication

image.png
  • 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返回给调用者。

相关文章

网友评论

      本文标题:ContentProvider要点

      本文链接:https://www.haomeiwen.com/subject/khsbpktx.html