ContentProvider启动流程示例解析

 更新时间:2023年03月02日 14:46: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
  • 调用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 /*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();
}

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

以上就是ContentProvider启动流程示例解析的详细内容,更多关于ContentProvider启动流程的资料请关注脚本之家其它相关文章!

相关文章

  • Android动画之雷达扫描效果

    Android动画之雷达扫描效果

    雷达扫描效果在我们日常会经常看到,比如在新浪微博上有一个雷达功能,感觉类似于微信附近的人。只是多了一个类似于雷达扫描效果的动画,某些知名安全软件也有这样的雷达效果,因此今天在这里小编带着大家学习一下。
    2016-08-08
  • Android编程实现短信收发及语音播报提示功能示例

    Android编程实现短信收发及语音播报提示功能示例

    这篇文章主要介绍了Android编程实现短信收发及语音播报提示功能,结合实例形式分析了Android实现短信的接收、发送以及相应的语音播报提示功能相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • flutter 实现点击下拉栏微信右上角弹出窗功能

    flutter 实现点击下拉栏微信右上角弹出窗功能

    这篇文章主要介绍了flutter 实现弹出窗点击下拉栏微信右上角弹出窗功能,这段代码使用的是PopupRoute这个路由类进行实现 的,分步骤通过实例代码讲解的非常详细,需要的朋友可以参考下
    2021-05-05
  • Android利用Dom对XML进行增删改查操作详解

    Android利用Dom对XML进行增删改查操作详解

    使用DOM进行增删改查,这个是DOM的优势所在,其实代码很简单,不需要过多的解释,下面这篇文章主要给大家介绍了关于Android利用Dom对XML进行增删改查操作的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2018-01-01
  • Android开发实现按钮点击切换背景并修改文字颜色的方法

    Android开发实现按钮点击切换背景并修改文字颜色的方法

    这篇文章主要介绍了Android开发实现按钮点击切换背景并修改文字颜色的方法,涉及Android界面布局与相关属性设置技巧,需要的朋友可以参考下
    2018-01-01
  • Android异步消息处理机制实现原理详解

    Android异步消息处理机制实现原理详解

    这篇文章主要介绍了Android异步消息处理机制实现原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Android ListView获得选项中的值

    Android ListView获得选项中的值

    本篇文章主要介绍Android ListView,在Android开发过程中经常会用到ListView 组件并有监听事件,这里给大家一个简单实例,来说明如何得到ListView选项中的值
    2016-07-07
  • Android中自定义控件之液位指示器

    Android中自定义控件之液位指示器

    这篇文章主要介绍了Android中自定义控件之液位指示器 方法的相关资料,需要的朋友可以参考下
    2016-03-03
  • Android8.1 通过黑名单屏蔽系统短信和来电功能

    Android8.1 通过黑名单屏蔽系统短信和来电功能

    最近小编接到一个新的需求,需要将8.1 设备的来电功能和短信功能都屏蔽掉,特殊产品就是特殊定制。接下来通过本文给大家介绍Android8.1 通过黑名单屏蔽系统短信和来电功能,需要的朋友参考下吧
    2019-05-05
  • Android开发实现的导出数据库到Excel表格功能【附源码下载】

    Android开发实现的导出数据库到Excel表格功能【附源码下载】

    这篇文章主要介绍了Android开发实现的导出数据库到Excel表格功能,涉及Android数据库及Excel表格相关操作技巧,并附带完整源码供读者下载参考,需要的朋友可以参考下
    2018-03-03

最新评论