ContentProvider启动流程示例解析
作者:尹学姐 发布时间:2023-07-31 03:57:34
标签: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 /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
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
的启动。
来源:https://juejin.cn/post/7205161917421781029


猜你喜欢
- 具体代码如下所示:package com.example.studyapplication.fragment;import android.
- Java 静态绑定与动态绑定 最
- 添加方法:选择项目->引用->右击“添加引用”->选择COM 找到上面组件—>点击“确定”。实现代码如下: 
- 下面是android SDK中API中的主要java包的功能简介: android.app :提供高层的程序模型、提供基本的运行环
- Android 读取文件内容实现方法,这里整理了几种方法,大家需要可以看下。如果要打开存放在/data/data/<package n
- 最近,Oracle 宣布 Java 14(或 Oracle JDK 14)公开可用。如果你想进行最新的实验或者开发的话,那么你可以试试在 L
- 1、spring原理内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其
- 本文实例讲述了Android使用ListView实现下拉刷新及上拉显示更多的方法。分享给大家供大家参考,具体如下:今天得需求是做listvi
- 同线程回收对象上一小节剖析了从recycler中获取一个对象, 这一小节分析在创建和回收是同线程的前提下, recycler是如何进行回收的
- 前言WorkManager 是 Android Jetpack 中的新组件,用于负责管理后台任务。关于这个组件的介绍就不多说了,网上到处都是
- 这一篇网络爬虫的实现就要联系上大数据了。在前两篇java实现网络爬虫和heritrix实现网络爬虫的基础上,这一次是要完整的做一次数据的收集
- 如今RxJava和Retrofit的结合使用估计已经相当普遍了,自己工作中也是一直都在使用。在使用的过程中我们都会对其进行封装使用,GitH
- 前言借用《Effactive Java》这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点
- 本文实例为大家分享了Android投票进度条的具体代码,供大家参考,具体内容如下效果展示功能属性介绍<!-- MatchSupport
- 一.使用MSScriptControl 到微软的网站上下载Windows Script Control,它是一个ActiveX(R) 控件,
- 本文实例为大家分享了C# GDI+实现时钟表盘的具体代码,供大家参考,具体内容如下一、设计如下图界面按键“打开时钟&am
- 如下所示:public static String reThreeStr(String ss){boolean result= ss.mat
- 一、 添加 maven 依赖<dependency> <groupId>com.google.guava
- 已经下过好几次了,现在还是忘了。就把过程直接放上面了。下次再换电脑就直接可以看。。。0.下载之前需要把JDK安装和配置好,点这里:https
- 经过一番搜索发现,java操纵excel文件常用的有jxl和poi两种方式,孰好孰坏看自己需求而定。其中最主要的区别在于jxl不支持.xls