• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

HomeLauncher启动

android 搞代码 3年前 (2022-03-01) 35次浏览 已收录 0个评论

该文章解说下Launcher启动相干常识,并更正网上某些文章的谬误点.

本篇为鸡生蛋系列第五篇文章, 也即最初篇, 终于能够完结该系列了。

  1. Linux input零碎数据上报流程
  2. Android InputManager剖析
  3. AMS startActivity()
  4. activity显示过程梳理
  5. HomeLauncher启动

[代码: Android 11]

http://aosp.opersys.com/xref/…

[代码: Android 8.1]

http://aosp.opersys.com/xref/…

startHomeActivityLocked()

搜网上材料, 好些文章说launcher启动是在

ActivityManagerService.systemReady() --> startHomeActivityLocked()

时启动的, 那这个对不对呢? 这个其实对,也不对,(也可能是他们剖析的版本太老了吧)。

说它不对咱们前面点再说, 先简略看下这个流程代码。

AMS(ActivityManagerService) systemReady()是在SystemServer startOtherServices()时调用的, 其过程整顿如下:

<code class="java">frameworks/base/services/java/com/android/server/SystemServer.java
main(String[] args)
  + new SystemServer().run();
      + startBootstrapServices(t);
      + startCoreServices(t);
      + startOtherServices(t);
          + mActivityManagerService.systemReady(() -> {
                ......// callback参数会里启动system ui, 有须要的可关注下
                startSystemUi(context, windowManagerF);
                ......
            )

对于 < Android10的版本, AMS的systemReady()进一步通过 startHomeActivityLocked(), 好些文章认为在此就启动了launcher

<code class="java">frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
......
        startHomeActivityLocked(currentUserId, "systemReady");

boolean startHomeActivityLocked(int userId, String reason) {
    ......
    // home intent
    Intent intent = getHomeIntent();
    // 失去该intent应该启哪个利用
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
            ......
            // 启动该activity, 前面流程和利用启动流程差不多,就不说了
            mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);

具体的代码解说可网上搜下相干文章, 网上有很多,
好,

<big>完!</big>

可是…

事件真的完了吗?

我之前也始终认为是这样的, 我想着他人都写了一大堆这类文章,多我一个也没啥意思,所以就想用逆向剖析的办法来看看,后果这一剖析,发现有些不对的中央.

逆向剖析

所谓逆向剖析,就是我假如我不晓得答案,也不太分明framework咋玩的,从launcher的onCreate()动手,看能不能失去雷同的后果.

所采纳的办法呢,也很简略,也就是打印调用堆栈,而后看代码持续剖析,持续打印调用堆栈….反复

具体的说,安卓java层常见的打印堆栈办法有如下几种:

  • Throwable
<code class="java">Log.i(TAG, Log.getStackTraceString(new Throwable()));
  • Exception
<code class="java">Exception e = new Exception("testandroid this is a log");  
e.printStackTrace();  
也即简化为
new Exception("testandroid this is a log").printStackTrace();
  • RuntimeException
<code class="java">RuntimeException callStack = new RuntimeException("callstack:  ");  
callStack.fillInStackTrace();  
Log.e(TAG, "testandroid this is a log: ", callStack);

那咱们就实战一把, 先在Launcher里加上log,
留神:
我实战用的代码为android8.1的源码, 因为我目前就只有该平台的开发机.
堆栈也不重要, 看下分析方法就行.

<code class="diff">/home/atom/work/code/suiren_master/LINUX/android/packages/apps/Launcher3
@@ -350,6 +350,13 @@ public class Launcher extends BaseActivity
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        RuntimeException callStack = new RuntimeException("callstack:  ");
+        callStack.fillInStackTrace();
+        Log.e(TAG,"testandroid this is a log: ", callStack);

打印出的堆栈如下:

<code class="txt">Launcher: testandroid this is a log: 
Launcher: java.lang.RuntimeException: callstack:
Launcher:  at com.android.launcher3.Launcher.onCreate(Launcher.java:354)
Launcher:  at android.app.Activity.performCreate(Activity.java:7082)
Launcher:  at android.app.Activity.performCreate(Activity.java:7073)
Launcher:  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
Launcher:  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2737)
Launcher:  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2862)
Launcher:  at android.app.ActivityThread.-wrap11(Unknown Source:0)
Launcher:  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1595)
Launcher:  at android.os.Handler.dispatchMessage(Handler.java:106)
Launcher:  at android.os.Looper.loop(Looper.java:164)
// ActivityThread.main()函数, 通过AMS startActivity()章节剖析可晓得其通过zyogote fork后会调用该函数
Launcher:  at android.app.ActivityThread.main(ActivityThread.java:6524)
Launcher:  at java.lang.reflect.Method.invoke(Native Method)
Launcher:  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
Launcher:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

后果加了第一个log,就发现了些问题,

问题1:
因为咱们代码是有开机向导的,后果发现要开机向导完结后才调用Launcher的onCreate()

我在AMS startHomeActivityLocked()也加了log, systemReady()时的确是有调用到, 然而没有Launcher的onCreate(), 问题1之后才有

我先把逆向剖析讲完再回头看这两问题

从下面堆栈看, 利用调到了ActivityThread.main(), 如果再沿着这个剖析可能就很难了,这个就须要点背景常识了.
在剖析AMS startActivity()时咱们晓得, 利用会通过zygoteProcess.start()申请zyogote fork利用,

<code class="java">frameworks/base/core/java/android/os/Process.java
public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int runtimeFlags, int mountExternal,
                              int targetSdkVersion,
                              ......) {
    // 留神 processClass 为 "android.app.ActivityThread"
    return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}

strat()会进一部调用startViaZygote(), 咱们调加启动利用流程调用栈应该在如下中央

<code class="diff">frameworks/base/services/core/java/android/os/ZygoteProcess.java
    private Process.ProcessStartResult startViaZygote(final String processClass,....
 
+        RuntimeException callStack = new RuntimeException("callstack:  ");
+        callStack.fillInStackTrace();
         // 将niceName打印进去不便看启动哪个利用
+        Log.e(LOG_TAG, "testandroid this is a log: " + processClass + " niceName:" + niceName + " ", callStack);

其堆栈如下

// com.android.launcher3 启动
ZygoteProcess: testandroid this is a log: android.app.ActivityThread niceName:com.android.launcher3
ZygoteProcess: java.lang.RuntimeException: callstack:
ZygoteProcess:     at android.os.ZygoteProcess.startViaZygote(ZygoteProcess.java:346)
ZygoteProcess:     at android.os.ZygoteProcess.start(ZygoteProcess.java:208)
ZygoteProcess:     at android.os.Process.start(Process.java:462)
ZygoteProcess:     at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4007)
ZygoteProcess:     at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3829)
ZygoteProcess:     at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3715)
ZygoteProcess:     at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1599)
ZygoteProcess:     at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2755)
ZygoteProcess:     at com.android.server.am.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:2268)
ZygoteProcess:     at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2102)
ZygoteProcess:     at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1499)
ZygoteProcess:     at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:1426)
// activityPaused
ZygoteProcess:     at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:7691)
// binder通信, 调用栈断了
ZygoteProcess:     at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:317)
ZygoteProcess:     at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2980)

这里onTransactd()是binder通信, 所以须要晓得binder proxy侧谁调用该binder函数, 而后在那儿增加日志

通过搜代码,还好,就一个中央, 能够在该中央加上日志

<code class="java">frameworks/base/core/java/android/app/ActivityThread.java
private void handlePauseActivity(IBinder token, boolean finished,....
......
                  // 调用activityPaused(), 可在此加上日志,
                  ActivityManager.getService().activityPaused(token);

因为两头有handler也会导致栈信息断, 对handler message这种导致的栈断只能剖析代码看谁在sendMessage()给它了
具体过程了加的日志就不说了, 其流程为
schedulePauseActivity() --> sendMessage(PAUSE_ACTIVITY_FINISHING/PAUSE_ACTIVITY) --> handlePauseActivity() --> ActivityManager.getService().activityPaused(token);

进一步的堆栈如下:

<code class="txt">// 其是通过 ActivityStack.java schedulePauseActivity 调用到了
ActivityManager: testandroid ActivityStack.java schedulePauseActivity java.lang.Throwable
ActivityManager:   at com.android.server.am.ActivityStack.startPausingLocked(ActivityStack.java:1359)
ActivityManager:   at com.android.server.am.ActivityStack.finishActivityLocked(ActivityStack.java:3821)
ActivityManager:   at com.android.server.am.ActivityStack.finishActivityLocked(ActivityStack.java:3763)
ActivityManager:   at com.android.server.am.ActivityStack.requestFinishActivityLocked(ActivityStack.java:3611)
// 谁在调用finishActivity() ?
ActivityManager:   at com.android.server.am.ActivityManagerService.finishActivity(ActivityManagerService.java:5283)

堆栈的最初为 finishActivity(), 那么谁在调用呢?
调用finishActivity()的中央也有好几个,可在各个中央加上代码, 最终是在 Activity.java finish() 调用的
代码如下:

<code class="java">frameworks/base/core/java/android/app/Activity.java
private void finish(int finishTask) {
......
            if (ActivityManager.getService()
                    .finishActivity(mToken, resultCode, resultData, finishTask)) {

堆栈如下:

<code class="txt">Activity.java finish()
System.err: java.lang.Exception: testandroid Activity.java finish
System.err:    at android.app.Activity.finish(Activity.java:5562)
System.err:    at android.app.Activity.finish(Activity.java:5600)
System.err:    at com.android.settings.FallbackHome.maybeFinish(FallbackHome.java:129)
System.err:    at com.android.settings.FallbackHome.-wrap0(Unknown Source:0)
System.err:    at com.android.settings.FallbackHome$1.onReceive(FallbackHome.java:106)

至此, 咱们终于看到了, 是在 FallbackHome onReceive() 时调用了finish(), 而后才把launcher启动起来.

那咱们看下代码(剖析看正文):

<code class="java">packages/apps/Settings/src/com/android/settings/FallbackHome.java
protected void onCreate(Bundle savedInstanceState) {
    ......
    // 注册了用户解锁的 receiver
    registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
    // 留神这里的maybeFinish并没有调起launcher
    maybeFinish();
}

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 接到用户解锁,而后调maybeFinish()
        maybeFinish();
    }
};

private void maybeFinish() {
    // 用户是否解锁, 如果onCreate()-->maybeFinish()时如果用户没解锁则啥也不做
    if (getSystemService(UserManager.class).isUserUnlocked()) {
        final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
                .addCategory(Intent.CATEGORY_HOME);
        ......
            Log.d(TAG, "User unlocked and real home found; let's go!");
            getSystemService(PowerManager.class).userActivity(
                    SystemClock.uptimeMillis(), false);
            // 调用finish完结本人activity
            finish();
        }
    }
}

这时候事件进一步明了了,
FallbackHome onReceive() 接到用户解锁播送时调用了finish(),本人的activity退出时才把launcher启动

那 startHomeActivityLocked() 是不是在Launcher启动时就齐全没作用呢?

发现有日志:

ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.launcher3/.Launcher} from uid 0

而后找到代码所在中央,通过打印堆栈发现其实是有调用的.

<code class="txt">ActivityManager: ActivityStarter.java testandroid this is a log:
ActivityManager: java.lang.RuntimeException: callstack:
ActivityManager:   at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:331)
ActivityManager:   at com.android.server.am.ActivityStarter.startActivityLocked(ActivityStarter.java:283)
ActivityManager:   at com.android.server.am.ActivityStarter.startHomeActivityLocked(ActivityStarter.java:655)
ActivityManager:   at com.android.server.am.ActivityManagerService.startHomeActivityLocked(ActivityManagerService.java:4241)
ActivityManager:   at com.android.server.am.ActivityStackSupervisor.resumeHomeStackTask(ActivityStackSupervisor.java:781)
ActivityManager:   at com.android.server.am.ActivityStack.resumeTopActivityInNextFocusableStack(ActivityStack.java:2779)
ActivityManager:   at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2326)
ActivityManager:   at com.android.server.am.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:2268)
ActivityManager:   at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2107)
ActivityManager:   at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2091)
ActivityManager:   at com.android.server.am.ActivityStack.finishCurrentActivityLocked(ActivityStack.java:3943)
ActivityManager:   at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1458)
ActivityManager:   at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:1426)
ActivityManager:   at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:7686)
ActivityManager:   at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:317)
ActivityManager:   at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2980)

Provision

让咱们回到问题1

因为咱们代码是有开机向导的,后果发现要开机向导完结后才调用Launcher的onCreate()

Android默认的开机向导为 Provision, 其代码也很简略, 次要为
设置一些数据库值 –> 把本人disable, 之后home intent时就不会找到本人了 –> 完结本人

<code class="java">packages/apps/Provision/src/com/android/provision/DefaultActivity.java
protected void onCreate(Bundle icicle) {
    ......
    Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
    Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
    Settings.Secure.putInt(getContentResolver(), Settings.Secure.TV_USER_SETUP_COMPLETE, 1);

    // remove this activity from the package manager.
    // disable该activity
    PackageManager pm = getPackageManager();
    ComponentName name = new ComponentName(this, DefaultActivity.class);
    pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

    // terminate the activity.
    // 完结该activity
    finish();
}

HOME intent优先级问题

AMS systemReady() –> startHomeActivityLocked() 时获取到的为 FallbackHome

<code class="java">boolean startHomeActivityLocked(int userId, String reason) {
    // 取得home intent
    Intent intent = getHomeIntent();
    //  失去该intent应该启哪个利用
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
    ......
            mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);

日志(零碎里还有别的响应home的activity, 这里就没列出了,次要看这三个):

ActivityManager: startHomeActivityLocked ?? act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.settings/.FallbackHome
// 开机向导设置完之后DefaultActivity会禁用,之后启机不会再匹配上
ActivityManager: startHomeActivityLocked ?? act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.provision/.DefaultActivity
ActivityManager: startHomeActivityLocked ?? act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.launcher3/.Launcher

可是看了其优先级设置,

<code class="xml">packages/apps/Settings/AndroidManifest.xml
<activity android:name=".FallbackHome"
    ...... // FallbackHome 优先级 -1000
    <intent-filter android:priority="-1000">

packages/apps/Provision/AndroidManifest.xml
<activity android:name="DefaultActivity"
......// DefaultActivity 优先级 3
    <intent-filter android:priority="3">

FallbackHome 优先级 -1000, 为最小
DefaultActivity 优先级 3
Launcher3 没有设置

实践上来说,有开机向导时,应该 DefaultActivity 匹配上, 之后重启应该是 Launcher3 匹配上,
那么为啥systemReady()时为FallbackHome, 或者说为啥老是 FallbackHome 先匹配上?
按理来说其优先级最低,应该最初匹配上才对啊.

resolveActivityInfo()流程如下:

<code class="java">resolveActivityInfo() / ActivityManagerService.java
  + AppGlobals.getPackageManager().resolveIntent()
      + resolveIntent() / PackageManagerService.java 
          + resolveIntentInternal()
              + queryIntentActivitiesInternal() // 查问所有符合条件的activities
              |   + result = filterIfNotSystemUser(mActivities.queryIntent(.....))
              |       + super.queryIntent(....) / class ActivityIntentResolver
              |           + buildResolveList(....firstTypeCut, finalList, userId); / IntentResolver.java
              + chooseBestActivity() // 抉择最好的那个

在下面流程中,会先查问出所有符合条件的activities, 而后选出最好的那个, 有须要的能够在这儿查看选取规定.
本认为是chooseBestActivity()时DefaultActivity/Launcher3不是最好的, 加上log确认原来在 queryIntentActivitiesInternal() 时最开始就只有 FallbackHome

间接启动

buildResolveList()之后可简略看看调查过程和正文, 因为代码老是变,也没多大意义, 次要的是提下前面的调查结果和发现了 间接启动 这么个对我来说的新货色.

<code class="java">frameworks/base/services/core/java/com/android/server/IntentResolver.java
private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
        boolean debug, boolean defaultOnly, String resolvedType, String scheme,
        F[] src, List<R> dest, int userId) {
        ......
        match = filter.match(action, resolvedType, scheme, data, categories, TAG);
        if (match >= 0) {
            // 关上这里的日志发现其实最后时 FallbackHome DefaultActivity Launcher 都有match的
            if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
                    Integer.toHexString(match) + " hasDefault="
                    + filter.hasCategory(Intent.CATEGORY_DEFAULT));
            if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
                // 然而后两者返回的为null
                final R oneResult = newResult(filter, match, userId);
                if (oneResult != null) {
                    // 如果不为null才退出到dest里
                    dest.add(oneResult);

newResult 对于activity intent来说实现在
PackageManagerService.java
......
final class ActivityIntentResolver
        extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {

    protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
            int match, int userId) {
        if (!sUserManager.exists(userId)) return null;
        // 这里返回为null, 因为DefaultActivity设置后会把本人禁用, 所以重启时他没匹配上倒也能够了解,
        // 可是为啥起机后 Launcher 也在 FallbackHome 后匹配上呢? 能够持续考察
        if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
            return null;
        }

frameworks/base/services/core/java/com/android/server/pm/Settings.java
boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
    final PackageSetting ps = mPackages.get(componentInfo.packageName);
    if (ps == null) return false;

    final PackageUserState userState = ps.readUserState(userId);
    // 这里反回false
    return userState.isMatch(componentInfo, flags);
}

frameworks/base/core/java/android/content/pm/PackageUserState.java
public boolean isMatch(ComponentInfo componentInfo, int flags) {
    final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp();
    final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
    if (!isAvailable(flags)
            && !(isSystemApp && matchUninstalled)) return false;
    // Enable判断
    if (!isEnabled(componentInfo, flags)) return false;
    if ((flags & MATCH_SYSTEM_ONLY) != 0) {
        if (!isSystemApp) {
            return false;
        }
    }

    final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
            && !componentInfo.directBootAware;
    final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
            && componentInfo.directBootAware;
    // 对Launcher来说, 这里起机时刚开始反回false, 之后返回true
    return matchesUnaware || matchesAware;
}

看到最初 DIRECT_BOOT_UNAWARE DIRECT_BOOT_AWARE componentInfo.directBootAwar 这是啥呢?

这个其实就是对间接启动利用判断,

间接启动材料可看:
https://developer.android.goo&#8230;
简略说就是未解锁时能够运行的程序,比如说未解锁拍照.

FallbackHome 所在的设置是有反对间接启动, Launcher 不反对, 所以FallbackHome总是会先匹配, 解锁后Launcher才有机会匹配上.

<code class="xml">packages/apps/Settings/AndroidManifest.xml
<application android:label="@string/settings_label"
        ...// FallbackHome 所在的设置反对间接启动      
         android:directBootAware="true">

总结

  1. 对home intent的响应是有优先级的, 所以AMS systemReady()调用 start home时并不一定会启动launcher, 当其它优先级的home activity响应完后才有可能是 launcher
  2. 一般说来, launcher启动是在, settings FallbackHome 监听到解锁后调用finish() 完结本人时,才把launcher启动起来
  3. 因为 settings 反对 间接启动, launcher 不反对, 所以未解锁时launcher不会匹配到home intent.
  4. 一些home intent的优先级
package activity 优先级
com.android.settings CryptKeeper 10
com.android.provision DefaultActivity 3
com.android.launcher3 Launcher 默认
com.android.settings FallbackHome -1000
  1. Android 11 AMS systemRead() startHomeOnDisplay() 流程简略整顿:
<code class="java">frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
  + // goingCallback 回调, 这里会启动systemui
  | if (goingCallback != null) goingCallback.run();
  + // start user
  | mSystemServiceManager.startUser(t, currentUserId);
  + // 启动persistent利用
  | startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
  + // 启动所有屏的 Home, 
  | mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
  | // mAtmInternal为ActivityTaskManagerInternal类型,其最终实现在
  | // ActivityTaskManagerService.java
  + // final class LocalService extends ActivityTaskManagerInternal
      + mRootWindowContainer.startHomeOnDisplay(...) / ActivityTaskManagerService.java
          + startHomeOnTaskDisplayArea(...) / RootWindowContainer.java
              + if (taskDisplayArea == getDefaultTaskDisplayArea()) {
              |     homeIntent = mService.getHomeIntent();
              |     // 失去默认屏home intent的activity
              |     aInfo = resolveHomeActivity(userId, homeIntent);
              | } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
              |     // 失去第二个屏home intent的activity
              |     Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
              +
              + mService.getActivityStartController().startHomeActivity(...)
                  +
                  | ActivityStartController.java
                  | void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
                  |         TaskDisplayArea taskDisplayArea) {...
                  |      // 多屏相干, 启动到哪个屏设置
                  |     final int displayId = taskDisplayArea.getDisplayId();
                  |     options.setLaunchDisplayId(displayId);
                  |     options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
                  |             .toWindowContainerToken());
                  |     ......
                  | 
                  |     mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                  |             .setOutActivity(tmpOutRecord)
                  |             .setCallingUid(0)
                  |             .setActivityInfo(aInfo)
                  |             .setActivityOptions(options.toBundle())
                  +             .execute();

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:HomeLauncher启动

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址