(二十)四大组件的工作过程-ContentProvider
ContentProvider是一种内容共享形组件,通过Binder向其他组件乃至其他应用提供数据,当其所在的进程启动时,CP会同时被启动并被发布到AMS中。注意:这个时候CP的onCreate方法会先于Application的onCreate方法执行。
一个应用启动时,入口方法为ActivityThread的main方法,它是一个静态方法,在它内部会创建ActivityThread的实例并创建主线程的消息队列,在他的attach方法中会远程调用AMS的attachApplication方法并将ActivityThread对象提供给AMS。在attachApplication方法里会调用ApplicationThread的bindApplication方法,此处会经过mH Handler切换到ActivityThread里去执行,具体方法是handleBindApplication方法,在该方法里ActivityThread会加载ContentProvider并创建Application对象。
访问ContentProvider需要通过ContetnResolver,它是一个抽象类,通过Context的getContentResolver方法获得的实际上是ApplicationContentResolver对象。ApplicationContentResolver继承了ContentResolver并实现了其中的方法。在此分析query方法
1、首先会获取IContentProvider对象,无论通过acquireUnstableProvider方法还是直接通过acquireProvider方法,本质都一样,都通过acquireProvider方法来获取ContentPrivoder。
2、ApplicationContentResolver的acquireProvider方法直接调用ActivityThread的acquireProvider方法。该方法里首先会判断是否已存在目标ContentProvider对象,存在则直接返回,否则调用AMS的getContentProvider方法让其启动目标ContentProvider,然后通过installProvider来修改引用计数;
3、程序启动ContentProvider首先会启动他所在的进程,进程的启动是通过startProcessLocked方法,内部主要通过Process的start方法完成,进程启动后入口方法是ActivityThread的main方法。
4、main方法里会创建ActivityThread实例并通过attach方法进行初始化操作,将ApplicationThread对象通过AMS的attachApplication方法跨进程传递给AMS,AMS完成ContentProvider的创建。
5、AMS的attachApplication方法调用attachApplicationLocked方法,内部又调用ApplicationThread的bindApplication方法,bindApplication方法会通过发送消息给H,得到消息后调用ActivityThread的handleBindApplication方法。
6、handleBindApplication方法完成以下步骤:a、创建ContextImpl和Instrumentation b、创建Application对象 c、启动当前进程的ContentProvider并调用其onCreate方法,installContentProviders方法完成启动工作,内部会遍历当前进程的ProviderInfo的列表并意义调用其installProvider方法,并将已启动的ContentProvider发不到AMS中(AMS的publishContentProviders方法),AMS会把他们存储到ProviderMap中,installProvider方法里创建CP对象,并通过attachInfo方法回调onCreate方法。
d、Instrumentation对象调用Application的onCreate方法。
注意:创建好的ContentProvider并不是原始的Contentrovider,而是ContetnProvidre的Binder对象IContetnProvider,IContentProvider的具体实现是ContentProviderNative和ContentProvider.Transport(继承ContentProviderNative),调用query方法实际是对调用的ContentProvider.Transport的query方法。