91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ContentProvider啟動流程源碼分析

發布時間:2023-03-02 15:28:48 來源:億速云 閱讀:134 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“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 /*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啟動流程源碼分析”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鹤岗市| 古丈县| 桂东县| 绥阳县| 东乌珠穆沁旗| 宜都市| 巫溪县| 蒙自县| 四子王旗| 灵丘县| 大同市| 织金县| 乌拉特中旗| 乐安县| 桓台县| 平安县| 茂名市| 土默特左旗| 柞水县| 长顺县| 富平县| 婺源县| 柳州市| 东城区| 济阳县| 昭苏县| 井冈山市| 永顺县| 乐昌市| 萨迦县| 台中市| 阿荣旗| 漳州市| 郑州市| 陆良县| 贡觉县| 岑巩县| 方山县| 安徽省| 宜宾市| 林西县|