日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

从源码角度看Android系统Launcher在开机时的启动过程

發(fā)布時(shí)間:2025/1/21 Android 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从源码角度看Android系统Launcher在开机时的启动过程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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在開(kāi)機(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


<permissionandroid:name="com.android.launcher3.permission.READ_SETTINGS"android:permissionGroup="android.permission-group.SYSTEM_TOOLS"android:protectionLevel="normal"android:label="@string/permlab_read_settings"android:description="@string/permdesc_read_settings"/> <permissionandroid:name="com.android.launcher3.permission.WRITE_SETTINGS"android:permissionGroup="android.permission-group.SYSTEM_TOOLS"android:protectionLevel="signatureOrSystem"android:label="@string/permlab_write_settings"android:description="@string/permdesc_write_settings"/><uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" /> <uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" /> <uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS" /><applicationandroid:backupAgent="com.android.launcher3.LauncherBackupAgent"android:fullBackupOnly="true"android:fullBackupContent="@xml/backupscheme"android:hardwareAccelerated="true"android:icon="@drawable/ic_launcher_home"android:label="@string/derived_app_name"android:theme="@style/LauncherTheme"android:largeHeap="@bool/config_largeHeap"android:restoreAnyVersion="true"android:supportsRtl="true" ><activityandroid:name="com.android.launcher3.Launcher"android:launchMode="singleTask"android:clearTaskOnLaunch="true"android:stateNotNeeded="true"android:windowSoftInputMode="adjustPan|stateUnchanged"android:screenOrientation="nosensor"android:configChanges="keyboard|keyboardHidden|navigation"android:resizeableActivity="true"android:resumeWhilePausing="true"android:taskAffinity=""android:enabled="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.MONKEY"/></intent-filter></activity><activityandroid:name="com.android.launcher3.SettingsActivity"android:label="@string/settings_button_text"android:theme="@android:style/Theme.DeviceDefault.Settings"android:autoRemoveFromRecents="true"><intent-filter><action android:name="android.intent.action.APPLICATION_PREFERENCES" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity><providerandroid:name="com.android.launcher3.LauncherProvider"android:authorities="com.android.launcher3.settings"android:exported="true"android:writePermission="com.android.launcher3.permission.WRITE_SETTINGS"android:readPermission="com.android.launcher3.permission.READ_SETTINGS" /></application>

從上面可以看到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ì)專門(mén)寫(xiě)文闡述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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。