您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“ContentProvider啟動流程源碼分析”,內容詳細,步驟清晰,細節處理妥當,希望這篇“ContentProvider啟動流程源碼分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
ContentProvider
是內容提供者,可以跨進程提供數據。
大家都知道,ContentProvider
的啟動,是在Application的onCreate
方法之前的,所以ContentProvider
的初始化時間會影響整個App的啟動速度。
那ContentProvider
啟動流程具體是什么樣的呢?讓我們進入源碼的世界來一探究竟。
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
調用Application
的onCreate
方法
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(); }
在ContentProvider
的attachInfo
方法中,會調用onCreate
方法,完成ContentProvider
的啟動。
讀到這里,這篇“ContentProvider啟動流程源碼分析”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。