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界面一键变灰开发深色适配模式编程示例

    这篇文章主要为大家介绍了Android界面一键变灰开发深色适配模式编程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • Android通过startService实现文件批量下载

    Android通过startService实现文件批量下载

    这篇文章主要为大家详细介绍了Android通过startService实现文件批量下载的示例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • Android实现网络图片浏览功能

    Android实现网络图片浏览功能

    这篇文章主要为大家详细介绍了Android实现网络图片浏览功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Android IdleHandler使用方法详解

    Android IdleHandler使用方法详解

    这篇文章主要为大家介绍了Android IdleHandler使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • android 实现控件左右或上下抖动教程

    android 实现控件左右或上下抖动教程

    这篇文章主要介绍了android 实现控件左右或上下抖动教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Android实现截屏功能

    Android实现截屏功能

    这篇文章主要为大家详细介绍了Android实现截屏功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 详解Android使用Gradle统一配置依赖管理

    详解Android使用Gradle统一配置依赖管理

    本篇文章主要介绍了详解Android 使用 Gradle 统一配置依赖管理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • Android动态人脸检测的示例代码(脸数可调)

    Android动态人脸检测的示例代码(脸数可调)

    本篇文章主要介绍了Android动态人脸检测的示例代码(脸数可调),具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08
  • 详解Android版本适配:9.0 Pie

    详解Android版本适配:9.0 Pie

    这篇文章主要介绍了Android版本适配9.0 Pie,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Android和PC端通过局域网文件同步

    Android和PC端通过局域网文件同步

    这篇文章主要为大家详细介绍了Android和PC端通过局域网文件同步的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07

最新评论