中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

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

阿图什市| 监利县| 丘北县| 阜新市| 九江县| 芦溪县| 仙游县| 贵州省| 灵宝市| 贵定县| 闻喜县| 望都县| 永胜县| 山西省| 揭西县| 惠水县| 冕宁县| 同心县| 云林县| 新源县| 遵化市| 罗源县| 多伦县| 霍林郭勒市| 仁怀市| 湖北省| 宣城市| 托克托县| 龙井市| 河池市| 沈丘县| 鄂托克旗| 麦盖提县| 慈利县| 综艺| 中卫市| 黑河市| 留坝县| 和林格尔县| 嘉黎县| 固始县|