ContentProvider启动流程

还记得刚开始接触Android开发时,有个疑问一直没有深入研究:

为什么写C/Java 程序时开始的入口函数都是main方法,Android却是Application,Acitivty?

直到发现了ActivityThread的main方法;其实Android程序之所以给给开发者这个“印象”,是因为Android的框架做了深度封装,并且提供了他的开发API,就是基于Application和四大组件。

时序图

通过分析源码,我们提取核心的调用流程,其中深红色箭头代表发生了跨进程调用。

broadcast-receiver-flow

核心环节分析

ContentProvider注册

当他所在进程启动时,就会被执行,并发布到AMS中,他的oncreate比Application的oncreate执行更早。

在ActivityThread的main方法中,主要做了两件事:

  • 创建了一个新的ActivityThread实例,并且执行attch进行初始化
  • 为当前线程配置了Looper,开启了主线程的loop
public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    // ...
    Process.setArgV0("<pre-initialized>");
    Looper.prepareMainLooper();
    // ...
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }
    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

关于ActivityThread逻辑后续我们单独分析。

* attach中执行AMS.attachApplication, --> attachApplicationLocked, -->ApplicationThread.bindApplication--> 发送BIND_APPLICATION消息给H,--> handleBindApplication-->完成Application的创建和ContentProvider的创建,
* 创建ContextImpl, Instrumentation对象,创建Application对象,创建并启动Provider,调用其attachInfo,-->onCreate,最后跨进程发布到AMS保存起来,AMS.publishContentProviders

ContentProvider查询

回顾一下使用,首先从上下文调用getContentResolve获取ContentResolver对象; ContentResolver是个抽象类,在API 28中继承自她的子类有三个

  • ApplicationContentResolver, 它是ContextImpl的内部静态类,getContentResolver获取到的就是它了;
  • MockContentResolver, 看名字就知道是模拟的类,用于测试;
  • BridgeContentResolver, 也是mock类;

然后执行他的操作api:

  • query
  • insert
  • bulkInsert
  • applyBatch
  • delete
  • update
  • 等等
内容共享组件,可以给app或其他app提供数据,通Binder实现
* 当他所在进程启动时,就会被执行,并发布到AMS中,他的oncreate比Application的oncreate执行更早
* 应用启动时,入口函数是静态方法main,位于ActivityThread中,大致流程为,创建ActivityThread实例对象,创建主线程消息队列,attach方法中执行AMS.attachApplication,并提供ApplicationThread给AMS,ApplicationThread本身是一个Binder,
ContentProvider一般是单实例,可以通过android:multiprocess=true多实例,很少有使用场景

* 通过ContentResolver请求Provider服务,getContentResolver得到实现类为ApplicationContentResolver
* 当Provider所在进程未启动时,会先启动进程,触发Provider四个方法的任一个都可以先创建进程
* ApplicationResolver.acquireProvider, ActivityThread.acquireProvider, 从集合中判断是否已经存在,进行实例服用,否则执行AMS.getContentProvider,返回ContentProviderHolder对象,执行installProvider,会修改应用计数,最后返回Holder.provider
* AMS启动进程: 通过AMS.startProcessLocked, --> Process.start
新进程启动后,入口为ActivityThread.main
* main函数内容,创建ActivityThread,执行其attach方法,然后开始loop
* attach中执行AMS.attachApplication, --> attachApplicationLocked, -->ApplicationThread.bindApplication--> 发送BIND_APPLICATION消息给H,--> handleBindApplication-->完成Application的创建和ContentProvider的创建,
* 创建ContextImpl, Instrumentation对象,创建Application对象,创建并启动Provider,调用其attachInfo,-->onCreate,最后跨进程发布到AMS保存起来,AMS.publishContentProviders
powered by Gitbook最近更新 2019-10-27

results matching ""

    No results matching ""