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