一文帶你看懂Android Application啟動(dòng)流程是怎樣的
基于Android11-API30
總覽
- 獲取applicationThread,AMS這兩個(gè)Binder2.attach時(shí),將獲取applicationThread對(duì)象也傳遞到AMS進(jìn)程,請(qǐng)求遠(yuǎn)程調(diào)用通知AMS應(yīng)用進(jìn)程想要?jiǎng)?chuàng)建Application,此時(shí)AMS為服務(wù)端
- AMS收到消息,請(qǐng)求調(diào)用applicationThread的遠(yuǎn)程接口,此時(shí)AMS為客戶端
- applicationThread收到AMS的請(qǐng)求,通過Handler發(fā)起創(chuàng)建Application的處理任務(wù),后面就沒有遠(yuǎn)程接口調(diào)用了
- 通過反射創(chuàng)建Application的實(shí)例,通過Instrumentation啟動(dòng)Application的onCreate方法
詳細(xì)流程分析
從 ActivityThread.java 的main方法開始看;
public static void main(String[] args) { ... ActivityThread thread = new ActivityThread(); thread.attach(system=false, startSeq);//1 ... }
進(jìn)入attach
方法;
if(!system){ final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread, startSeq);//1 } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } }
非系統(tǒng)應(yīng)用流程,根據(jù) getSeervice和捕獲的RemoteException可以斷定,此處在使用Binder進(jìn)行遠(yuǎn)程接口調(diào)用。
轉(zhuǎn)身看下mAppThread是什么?
final ApplicationThread mAppThread = new ApplicationThread(); private class ApplicationThread extends IApplicationThread.Stub { //批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等 public final void schedule* //TODO 關(guān)鍵方法 public final void bindApplication(some args){}//1 //一堆dump方法,比如dumpMemory、dumpActivity等 }
可以看到,ApplicationThread是一個(gè)實(shí)現(xiàn)了遠(yuǎn)程接口的Binder客戶端,內(nèi)部封裝實(shí)現(xiàn)了很多遠(yuǎn)程接口。不過這個(gè)客戶端什么時(shí)候連接的服務(wù)器還未可知,沒有找到bindService關(guān)鍵字,反正此時(shí)應(yīng)該已經(jīng)連接上對(duì)應(yīng)的Service了。應(yīng)該是在RuntimeInit.java類中進(jìn)行應(yīng)用進(jìn)程啟動(dòng)時(shí)啟動(dòng)的。
回來看下前一步服務(wù)的實(shí)例IActivityManager.attachApplication()內(nèi)部的實(shí)現(xiàn)。
先獲取AMS的實(shí)例,此處獲取AMS實(shí)例代碼跟Activity啟動(dòng)流程中一致
public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
…獲取到AMS的Binder后,繼續(xù)查看ActivityManagerService.java中的attachApplication方法
public final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid, callingUid, startSeq); //1 Binder.restoreCallingIdentity(origId); } }
單例獲取AMS實(shí)例,AMS服務(wù)在系統(tǒng)啟動(dòng)就已經(jīng)注冊(cè)到ServiceManager了,此處直接去獲取Binder實(shí)例就行,ServiceManager以Binder池的方式管理注冊(cè)的Server。
AMS的attachApplication方法中進(jìn)入到attachApplicationLocked方法,撿能看懂的代碼看,跟著thread參數(shù)查看代碼。
private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { try { AppDeathRecipient adr = new AppDeathRecipient( app, pid, thread); thread.asBinder().linkToDeath(adr, 0);//1 app.deathRecipient = adr; } catch (RemoteException e) { app.resetPackageList(mProcessStats); mProcessList.startProcessLocked(app, new HostingRecord("link fail", processName), ZYGOTE_POLICY_FLAG_EMPTY); return false; } final ActiveInstrumentation instr2 = app.getActiveInstrumentation(); if (instr2 != null) {//2 thread.bindApplication(processName, appInfo, providerList, instr2.mClass, profilerInfo, instr2.mArguments, instr2.mWatcher, instr2.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, app.mDisabledCompatChanges); } else { thread.bindApplication(processName, appInfo, providerList, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, app.mDisabledCompatChanges); } }
先給ApplicationThread這個(gè)Binder上個(gè)死亡代理,根據(jù)這個(gè)死亡代理應(yīng)該可以找到對(duì)應(yīng)的Service是如何重新啟動(dòng)的,感興趣可以繼續(xù)深入,咱們繼續(xù)往下走。
此處調(diào)用到thread.bindApplication接口,前面咱們查看ApplicationThread時(shí)有看到,直接切入。
private class ApplicationThread extends IApplicationThread.Stub { //批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等 public final void schedule* //TODO 關(guān)鍵方法 public final void bindApplication(some args){ AppBindData data = new AppBindData(); ...一堆參數(shù) sendMessage(H.BIND_APPLICATION, data);//1 } //一堆dump方法,比如dumpMemory、dumpActivity等 }
到達(dá)咱們Android開發(fā)工程師比較熟悉的點(diǎn)了,封裝了一堆參數(shù)后,通過H這個(gè)Handler對(duì)象發(fā)了一條BIND_APPLICATION消息,咱們看看這條消息去哪了,直接跟進(jìn)BIND_APPLICATION這個(gè)消息的捕捉位置。
//消息分發(fā) class H extends Handler{ public void handleMessage(Message msg){ swich(msg.what){ case BIND_APPLICATION: AppBindData data = (AppBindData)msg.obj; handleBindApplication(data);//1 break; ...省略 } } }
進(jìn)入消息分發(fā)處理方法,這個(gè)方法比較長,注意閱讀能看懂的代碼,不求甚解,跟蹤data的處理。
private void handleBindApplication(AppBindData data) { //各種初始化,比如進(jìn)程名,應(yīng)用名,AsyncTask線程池的配置,時(shí)區(qū),網(wǎng)絡(luò)發(fā)現(xiàn) //Context的初始化 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); try { final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation)//1 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } final ComponentName component = new ComponentName(ii.packageName, ii.name); mInstrumentation.init(this, instrContext, appContext, component,//1 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); ... Application app; app = data.info.makeApplication(data.restrictedBackupMode, null);//2 mInstrumentation.onCreate(data.instrumentationArgs); mInstrumentation.callApplicationOnCreate(app);//3 }
通過反射實(shí)例化mInstrumentation對(duì)象,該對(duì)象為Android系統(tǒng)組件的管家,目前看可以控制Application和Activity的生命周期。
創(chuàng)建Application對(duì)象,進(jìn)去看下創(chuàng)建的代碼
//LoadApk.java #makeApplication public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation){ ... app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);//1 appContext.setOuterContext(app); ... } //Instrumentation.java #newApplication public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = getFactory(context.getPackageName()) .instantiateApplication(cl, className);//2 app.attach(context);//首先回調(diào)attachBaseContext方法 return app; } //AppComponentFactory #instantiateApplication public @NonNull Application instantiateApplication(@NonNull ClassLoader cl, @NonNull String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Application) cl.loadClass(className).newInstance();//3 }
可以看出最后還是通過反射初始化了Application。
最后通過mInstrumentation對(duì)象完成Application類的onCreate方法的調(diào)用。
mInstrumentation.callApplicationOnCreate(app);//1 //Instrumentation.java #callApplicationOnCreate public void callApplicationOnCreate(Application app) { app.onCreate(); }
到此這篇關(guān)于一文帶你看懂Android Application啟動(dòng)流程是怎樣的的文章就介紹到這了,更多相關(guān)Android Application 啟動(dòng)流程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
功能強(qiáng)大的Android滾動(dòng)控件RecyclerView
這篇文章主要為大家詳細(xì)介紹了功能強(qiáng)大的Android滾動(dòng)控件RecyclerView,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08基于Flutter制作一個(gè)火箭發(fā)射動(dòng)畫
北京時(shí)間10月16日0時(shí)23分,神舟十三號(hào)飛船成功發(fā)射,為慶祝這一喜事,本文將用Flutter制作一個(gè)火箭發(fā)射動(dòng)畫,感興趣的小伙伴可以動(dòng)手試一試2022-03-03Android 微信小視頻錄制功能實(shí)現(xiàn)詳細(xì)介紹
這篇文章主要介紹了Android 微信小視頻錄制功能實(shí)現(xiàn)詳解的相關(guān)資料,這里提供了具體的實(shí)現(xiàn)思路及代碼,需要的朋友可以參考下2016-11-11Android SwipeMenuListView框架詳解分析
這篇文章主要介紹了Android SwipeMenuListView框架詳解分析的相關(guān)資料,需要的朋友可以參考下2016-10-10Android開發(fā)手冊(cè)Chip監(jiān)聽及ChipGroup監(jiān)聽
這篇文章主要為大家介紹了Android開發(fā)手冊(cè)Chip監(jiān)聽及ChipGroup監(jiān)聽,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06Jetpack?Compose?實(shí)現(xiàn)一個(gè)圖片選擇框架功能
這篇文章主要介紹了Jetpack?Compose?實(shí)現(xiàn)一個(gè)圖片選擇框架,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06android-獲取網(wǎng)絡(luò)時(shí)間、獲取特定時(shí)區(qū)時(shí)間、時(shí)間同步的方法
本篇文章主要介紹了android-獲取網(wǎng)絡(luò)時(shí)間、獲取特定時(shí)區(qū)時(shí)間、時(shí)間同步,小編覺得不錯(cuò),現(xiàn)在就分享給大家,有興趣的可以了解一下。2016-12-12