从源码角度看Android系统Launcher在开机时的启动过程
Launcher是Android所有應(yīng)用的入口,用來(lái)顯示系統(tǒng)中已經(jīng)安裝的應(yīng)用程序圖標(biāo)。
Launcher本身也是一個(gè)App,一個(gè)提供桌面顯示的App,但它與普通App有如下不同:
-
Launcher是所有應(yīng)用的入口,可以管理應(yīng)用
-
Launcher是在Android系統(tǒng)啟動(dòng)后就要顯示給用戶的應(yīng)用
-
Launcher是頂部App,即任何應(yīng)用返回后都是到Launcher,不能再繼續(xù)返回
Launcher啟動(dòng)的入口是AMS的systemReady方法。
備注:本文是結(jié)合Android8.0的源碼看Android系統(tǒng)Launcher在開機(jī)時(shí)的啟動(dòng)過(guò)程
1. startBootstrapServices啟動(dòng)AMS
從前面的《從源碼角度看Android系統(tǒng)SystemServer進(jìn)程啟動(dòng)過(guò)程》一文中可知:在SystemServer的startBootstrapServices方法中已經(jīng)啟動(dòng)ActivityManagerService
代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java
深入到startBootstrapServices函數(shù)中:
private void startBootstrapServices() {...省略...//啟動(dòng)服務(wù)ActivityManagerServicemActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);...省略...}2. startOtherServices中調(diào)用AMS的systemReady方法
然后又在SystemServer的startOtherServices方法中調(diào)用了AMS的systemReady方法
代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java
深入到startOtherServices函數(shù)中:
private void startOtherServices() {...省略...//調(diào)用ActivityManagerService的systemReadymActivityManagerService.systemReady(() -> {Slog.i(TAG, "Making services ready");traceBeginAndSlog("StartActivityManagerReadyPhase");mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);...省略...}3. AMS的systemReady方法
代碼路徑:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
深入到systemReady函數(shù)中:
public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {traceLog.traceBegin("PhaseActivityManagerReady");...省略...//啟動(dòng)HomeActivity,即Launcher應(yīng)用的桌面ActivitystartHomeActivityLocked(currentUserId, "systemReady");...省略... }4. AMS的startHomeActivityLocked方法
代碼路徑:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
深入到startHomeActivityLocked函數(shù)中:
boolean startHomeActivityLocked(int userId, String reason) {//判斷工廠模式和mTopAction的值if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL&& mTopAction == null) { //注釋1return false;}//創(chuàng)建Launcher啟動(dòng)所需要的IntentIntent intent = getHomeIntent(); //注釋2ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);if (aInfo != null) {intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));aInfo = new ActivityInfo(aInfo);aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);ProcessRecord app = getProcessRecordLocked(aInfo.processName,aInfo.applicationInfo.uid, true);if (app == null || app.instr == null) { //注釋3intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);final String myReason = reason + ":" + userId + ":" + resolvedUserId;// 啟動(dòng)LaunchermActivityStarter.startHomeActivityLocked(intent, aInfo, myReason); //注釋4}} else {Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());}return true; }注釋解析:
-
注釋1處的mFactoryTest代表系統(tǒng)的運(yùn)行模式,系統(tǒng)的運(yùn)行模式分為三種:工廠模式、低級(jí)工廠模式和高級(jí)工廠模式。mTopAction用來(lái)描述第一個(gè)被啟動(dòng)Activity組件的Action,默認(rèn)值為Intent.ACTION_MAIN。所以注釋1處的意思就是mFactoryTest 等于FactoryTest.FACTORY_TEST_LOW_LEVEL且mTopAction等于null時(shí),直接返回false
-
注釋2處調(diào)用了getHomeIntent方法。具體實(shí)現(xiàn)如下:
Intent getHomeIntent() {Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);intent.setComponent(mTopComponent);intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {intent.addCategory(Intent.CATEGORY_HOME);}return intent;}
創(chuàng)建intent對(duì)象,并將mTopAction和mTopData傳入,mTopAction的值為Intent.ACTION_MAIN,并且如果系統(tǒng)運(yùn)行模式不是低級(jí)工廠模式,則將intent的Category設(shè)置為Intent.CATEGORY_HOME,并返回intent
- 注釋3處判斷如果Action是Intent.ACTION_MAIN,Category是Intent.CATEGORY_HOME的應(yīng)用程序是否啟動(dòng),如果沒(méi)有啟動(dòng),則走注釋4處的啟動(dòng)邏輯
這里看下Launcher的AndroidManifest文件:
代碼路徑:packages/apps/Launcher3/AndroidManifest.xml
從上面可以看到intent-filter中設(shè)置了android.intent.action.MAIN和android:name="android.intent.category.HOME,這樣com.android.launcher3.Launcher的Activity就成為了主Activity。
- 注釋4處是如果Launcher沒(méi)有啟動(dòng),就會(huì)調(diào)用ActivityStarter的startHomeActivityLocked方法來(lái)啟動(dòng)Launcher
5. ActivityStarter的startHomeActivityLocked方法
代碼路徑:frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
深入到startHomeActivityLocked函數(shù)中:
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {//將Launcher的堆棧移動(dòng)到頂部mSupervisor.moveHomeStackTaskToTop(reason); //注釋1mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent, //注釋2null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,null /*container*/, null /*inTask*/, "startHomeActivity: " + reason);if (mSupervisor.inResumeTopActivity) {// If we are in resume section already, home activity will be initialized, but not// resumed (to avoid recursive resume) and will stay that way until something pokes it// again. We need to schedule another resume.mSupervisor.scheduleResumeTopActivities();} }注釋解析:
-
注釋1處將Launcher的堆棧移到頂部,這也是為什么Launcher總是在所有APP頂部的原因
-
注釋2調(diào)用startActivityLocked方法啟動(dòng)Home Activity。startActivityLocked是Android系統(tǒng)啟動(dòng)所有Activity的入口,后面會(huì)專門寫文闡述Activity的啟動(dòng)過(guò)程
最終會(huì)進(jìn)入Launcher的onCreate方法中,到此Launcher就啟動(dòng)完成。
6. Launcher啟動(dòng)過(guò)程時(shí)序圖
非常感謝您的耐心閱讀,希望我的文章對(duì)您有幫助。歡迎點(diǎn)評(píng)、轉(zhuǎn)發(fā)或分享給您的朋友或技術(shù)群。
總結(jié)
以上是生活随笔為你收集整理的从源码角度看Android系统Launcher在开机时的启动过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 从源码角度看Android系统Syste
- 下一篇: 结合源码深入理解Android Cras