ContentProvider啟動(dòng)流程示例解析
正文
ContentProvider
是內(nèi)容提供者,可以跨進(jìn)程提供數(shù)據(jù)。
大家都知道,ContentProvider
的啟動(dòng),是在Application的onCreate
方法之前的,所以ContentProvider
的初始化時(shí)間會(huì)影響整個(gè)App的啟動(dòng)速度。
那ContentProvider
啟動(dòng)流程具體是什么樣的呢?讓我們進(jìn)入源碼的世界來一探究竟。
App啟動(dòng)
App啟動(dòng)時(shí),AMS會(huì)通過跨進(jìn)程Binder
調(diào)用,訪問到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,發(fā)送給ActivityThread的H sendMessage(H.BIND_APPLICATION, data); }
這個(gè)方法主要作用是,拼接AppBindData
,發(fā)送給ActivityThread
中的Handler mH
。在這個(gè)Handler
中,會(huì)處理Message
,然后調(diào)用handleBindApplication(data)
方法。
private void handleBindApplication(AppBindData data) { final InstrumentationInfo ii; // 創(chuàng)建 mInstrumentation 實(shí)例 if (ii != null) { //創(chuàng)建ContextImpl final ContextImpl appContext = ContextImpl.createAppContext(this, pi); try { //創(chuàng)建mInstrumentation實(shí)例 final ClassLoader cl = appContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) {} } else { mInstrumentation = new Instrumentation(); } Application app; try { // 創(chuàng)建 Application 實(shí)例 app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; // 如果不是backup模式,則調(diào)用installContentProvider,啟動(dòng)ContentProvider if (!data.restrictedBackupMode) { if (!ArrayUtils.isEmpty(data.providers)) { //啟動(dòng)ContentProvider installContentProviders(app, data.providers); mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } } try { //調(diào)用Application的onCreate mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { } } }
這個(gè)方法非常長,主要做的事情有以下四點(diǎn):
- 創(chuàng)建一個(gè)
ContentImpl
對(duì)象 - 創(chuàng)建一個(gè)
Instrument
對(duì)象 - 創(chuàng)建
Application
實(shí)例 - 如果不是
backup
模式,調(diào)用installContentProviders
,啟動(dòng)ContentProvider
- 調(diào)用
Application
的onCreate
方法
installContentProviders
private void installContentProviders(Context context, List<ProviderInfo> providers) { final ArrayList<ContentProviderHolder> results = new ArrayList<>(); // 遍歷所有的providers for (ProviderInfo cpi : providers) { // 開始啟動(dòng)ContentProvider ContentProviderHolder cph = installProvider(context, null, cpi, false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); results.add(cph); } // 將成功啟動(dòng)的provider存儲(chǔ)到AMS的mProviderMap中 ActivityManager.getService().publishContentProviders(getApplicationThread(), results); }
這個(gè)方法,循環(huán)遍歷所有待啟動(dòng)的ContentProvider
,調(diào)用installProvider
啟動(dòng)。
private ContentProviderHolder installProvider(Context context, ContentProviderHolder holder, ProviderInfo info, boolean noisy, boolean noReleaseNeeded, boolean stable) { // 反射創(chuàng)建ContentProvider final java.lang.ClassLoader cl = c.getClassLoader(); LoadedApk packageInfo = peekPackageInfo(ai.packageName, true); localProvider = cl.loadClass(className).newInstance(); provider = localProvider.getIContentProvider(); // 調(diào)用ContentProvider的attachInfo方法 localProvider.attachInfo(c, info); }
這個(gè)方法,通過反射創(chuàng)建ContentProvider
,然后調(diào)用attachInfo
方法。
private void attachInfo(Context context, ProviderInfo info, boolean testing) { // 調(diào)用onCreate方法 ContentProvider.this.onCreate(); }
在ContentProvider
的attachInfo
方法中,會(huì)調(diào)用onCreate
方法,完成ContentProvider
的啟動(dòng)。
以上就是ContentProvider啟動(dòng)流程示例解析的詳細(xì)內(nèi)容,更多關(guān)于ContentProvider啟動(dòng)流程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android通過startService實(shí)現(xiàn)文件批量下載
這篇文章主要為大家詳細(xì)介紹了Android通過startService實(shí)現(xiàn)文件批量下載的示例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-12-12Android實(shí)現(xiàn)網(wǎng)絡(luò)圖片瀏覽功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)網(wǎng)絡(luò)圖片瀏覽功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06android 實(shí)現(xiàn)控件左右或上下抖動(dòng)教程
這篇文章主要介紹了android 實(shí)現(xiàn)控件左右或上下抖動(dòng)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03詳解Android使用Gradle統(tǒng)一配置依賴管理
本篇文章主要介紹了詳解Android 使用 Gradle 統(tǒng)一配置依賴管理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01Android動(dòng)態(tài)人臉檢測的示例代碼(臉數(shù)可調(diào))
本篇文章主要介紹了Android動(dòng)態(tài)人臉檢測的示例代碼(臉數(shù)可調(diào)),具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08