ContentProvider启动流程源码分析
本文小编为大家详细介绍“ContentProvider启动流程源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“ContentProvider启动流程源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
ContentProvider
是内容提供者,可以跨进程提供数据。
大家都知道,ContentProvider
的启动,是在Application的onCreate
方法之前的,所以ContentProvider
的初始化时间会影响整个App的启动速度。
那ContentProvider
启动流程具体是什么样的呢?让我们进入源码的世界来一探究竟。
App启动
App启动时,AMS会通过跨进程Binder
调用,访问到ApplicationThread
种的bindApplication
方法。
public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings, String buildSerial, boolean autofillCompatibilityEnabled) { // 拼接AppBindData,发送给ActivityThread的H sendMessage(H.BIND_APPLICATION, data); }
这个方法主要作用是,拼接AppBindData
,发送给ActivityThread
中的Handler mH
。在这个Handler
中,会处理Message
,然后调用handleBindApplication(data)
方法。
private void handleBindApplication(AppBindData data) { final InstrumentationInfo ii; // 创建 mInstrumentation 实例 if (ii != null) { //创建ContextImpl final ContextImpl appContext = ContextImpl.createAppContext(this, pi); try { //创建mInstrumentation实例 final ClassLoader cl = appContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) {} } else { mInstrumentation = new Instrumentation(); } Application app; try { // 创建 Application 实例 app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; // 如果不是backup模式,则调用installContentProvider,启动ContentProvider if (!data.restrictedBackupMode) { if (!ArrayUtils.isEmpty(data.providers)) { //启动ContentProvider installContentProviders(app, data.providers); mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } } try { //调用Application的onCreate mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { } }}
这个方法非常长,主要做的事情有以下四点:
创建一个
ContentImpl
对象创建一个
Instrument
对象创建
Application
实例如果不是
backup
模式,调用installContentProviders
,启动ContentProvider
调用
Application
的onCreate
方法
installContentProviders
private void installContentProviders(Context context, List<ProviderInfo> providers) { final ArrayList<ContentProviderHolder> results = new ArrayList<>(); // 遍历所有的providers for (ProviderInfo cpi : providers) { // 开始启动ContentProvider ContentProviderHolder cph = installProvider(context, null, cpi, false , true , true ); results.add(cph); } // 将成功启动的provider存储到AMS的mProviderMap中 ActivityManager.getService().publishContentProviders(getApplicationThread(), results); }
这个方法,循环遍历所有待启动的ContentProvider
,调用installProvider
启动。
private ContentProviderHolder installProvider(Context context, ContentProviderHolder holder, ProviderInfo info, boolean noisy, boolean noReleaseNeeded, boolean stable) { // 反射创建ContentProvider final java.lang.ClassLoader cl = c.getClassLoader(); LoadedApk packageInfo = peekPackageInfo(ai.packageName, true); localProvider = cl.loadClass(className).newInstance(); provider = localProvider.getIContentProvider(); // 调用ContentProvider的attachInfo方法 localProvider.attachInfo(c, info); }
这个方法,通过反射创建ContentProvider
,然后调用attachInfo
方法。
private void attachInfo(Context context, ProviderInfo info, boolean testing) { // 调用onCreate方法 ContentProvider.this.onCreate();}
在ContentProvider
的attachInfo
方法中,会调用onCreate
方法,完成ContentProvider
的启动。
读到这里,这篇“ContentProvider启动流程源码分析”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341