我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ContentProvider启动流程源码分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

  • 调用ApplicationonCreate方法

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();}

ContentProviderattachInfo方法中,会调用onCreate方法,完成ContentProvider的启动。

读到这里,这篇“ContentProvider启动流程源码分析”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ContentProvider启动流程源码分析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

ContentProvider启动流程源码分析

本文小编为大家详细介绍“ContentProvider启动流程源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“ContentProvider启动流程源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。C
2023-07-05

ContentProvider启动流程示例解析

这篇文章主要为大家介绍了ContentProvider启动流程示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-02

SpringBoot启动流程SpringApplication源码分析

这篇“SpringBoot启动流程SpringApplication源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“S
2023-07-05

【SpringBoot3.0源码】启动流程源码解析 • 上

文章目录 初始化 SpringBoot启动类: @SpringBootApplicationpublic class AppRun { public static void main(String[] args
2023-08-23

RocketMQ源码解析broker 启动流程

这篇文章主要为大家介绍了RocketMQ源码解析broker启动流程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-23

SpringBoot启动流程SpringApplication准备阶段源码分析

这篇文章主要为大家介绍了SpringBoot启动流程SpringApplication准备阶段源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-14

SpringBoot启动流程入口参数创建对象源码分析

这篇文章主要为大家介绍了SpringBoot启动流程入口参数研究及创建对象源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-14

Android 系统启动流分析 &amp; Zygote启动流程分析

本文是基于Android 7.1进行分析       Zygote在Android系统扮演着不可或缺的角色,Android系统的启动首先需要Zygote参与,比如启动SystemService , 还有一个就是孵化应用的进程,比如我们创建一
2022-06-06

Tomcat源码分析 | 启动过程深度解析

在启动过程中,LifecycleBase 首先发出 STARTING_PREP 事件,StandardServer 额外还会发出 CONFIGURE_START_EVENT 和 STARTING 事件,通知 LifecycleListene

hadoop源码_hdfs启动流程_1_NameNode

执行start-dfs.sh脚本后,集群是如何启动的?本文阅读并注释了start-dfs脚本,以及namenode和datanode的启动主要流程流程源码。阅读源码前准备源码获取拉取Apache Hadoop官方源码https://github.com/apa
hadoop源码_hdfs启动流程_1_NameNode
2020-02-18

hadoop源码_hdfs启动流程_2_DataNode

执行start-dfs.sh脚本后,集群是如何启动的?本文阅读并注释了start-dfs脚本,以及datanode的启动主要流程流程源码。DataNode 启动流程脚本代码分析start-dfs.sh中启动datanode的代码:#--------------
hadoop源码_hdfs启动流程_2_DataNode
2015-05-22

01-MyBatis启动流程分析

目录 MyBatis简单介绍 启动流程分析 简单总结 附录 MyBatis内置别名转换 参考 MyBatis简单
2017-03-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录