安卓Launcher启动详解

目录

  • 一、概述
    • [1.1 核心源码](#1.1 核心源码)
    • [1.2 主要代码作用](#1.2 主要代码作用)
  • 二、源码分析
    • [2.1 第一阶段SystemServer 启动HomeActivity的调用阶段](#2.1 第一阶段SystemServer 启动HomeActivity的调用阶段)
    • [2.2 [RootActivityContainer.java] startHomeOnDisplay()](#2.2 [RootActivityContainer.java] startHomeOnDisplay())
      • [2.2.1 [ActivityTaskManagerService.java] getHomeIntent()](#2.2.1 [ActivityTaskManagerService.java] getHomeIntent())
      • [2.2.2 [RootActivityContainer.java] resolveHomeActivity()](#2.2.2 [RootActivityContainer.java] resolveHomeActivity())
    • [2.3 [ActivityStartController.java ] startHomeActivity()](#2.3 [ActivityStartController.java ] startHomeActivity())
      • [2.3.1 [ActivityStarter.java] execute()](#2.3.1 [ActivityStarter.java] execute())
      • [2.3.2 [ActivityStarter.java] startActivity()](#2.3.2 [ActivityStarter.java] startActivity())
      • [2.3.3 [RootActivityContainer.java] resumeFocusedStacksTopActivities()](#2.3.3 [RootActivityContainer.java] resumeFocusedStacksTopActivities())
      • [2.3.4 [ActivityStackSupervisor.java] startSpecificActivityLocked()](#2.3.4 [ActivityStackSupervisor.java] startSpecificActivityLocked())
      • [2.3.5 [ActivityManagerService.java] startProcess()](#2.3.5 [ActivityManagerService.java] startProcess())
      • [2.3.6 [ZygoteProcess.java] attemptZygoteSendArgsAndGetResult()](#2.3.6 [ZygoteProcess.java] attemptZygoteSendArgsAndGetResult())
    • [2.4 第二阶段Zygote fork一个Launcher进程的阶段](#2.4 第二阶段Zygote fork一个Launcher进程的阶段)
      • [2.4.1 [ZygoteInit.java] main()](#2.4.1 [ZygoteInit.java] main())
      • [2.4.2 [ZygoteConnection.java] processOneCommand()](#2.4.2 [ZygoteConnection.java] processOneCommand())
      • [2.4.3 [ZygoteConnection.java] handleChildProc()](#2.4.3 [ZygoteConnection.java] handleChildProc())
    • [2.5 第三个阶段,Launcher在自己的进程中进行onCreate等后面的动作](#2.5 第三个阶段,Launcher在自己的进程中进行onCreate等后面的动作)
      • [2.5.1 [ActivityThread.java] main()](#2.5.1 [ActivityThread.java] main())
      • [2.5.2 [ActivityManagerService.java] attachApplication()](#2.5.2 [ActivityManagerService.java] attachApplication())
      • [2.5.3 [ActivityStackSupervisor.java] realStartActivityLocked()](#2.5.3 [ActivityStackSupervisor.java] realStartActivityLocked())
      • [2.5.4 [TransactionExecutor.java] execute()](#2.5.4 [TransactionExecutor.java] execute())
      • [2.5.5 [ActivityThread.java] handleLaunchActivity()](#2.5.5 [ActivityThread.java] handleLaunchActivity())
      • [2.5.6 [ActivityThread.java] performLaunchActivity()](#2.5.6 [ActivityThread.java] performLaunchActivity())
  • 三、总结
  • 四、相关日志

一、概述

在Android10中,桌面应用Launcher由Launcher演变到Launcher2,再到现在的Launcher3,Google也做了很多改动。

Launcher不支持桌面小工具动画效果,Launcher2添加了动画效果和3D初步效果支持,从Android 4.4 (KK)开始Launcher默认使用Launcher3, Launcher3加入了透明状态栏,增加overview模式,可以调整workspace上页面的前后顺序,可以动态管理屏幕数量,widget列表与app list分开显示等功能。

本文主要研究Launcher3的启动过程。

1.1 核心源码

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

/frameworks/base/core/java/com/android/internal/os/Zygote.java

/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

/frameworks/base/services/java/com/android/server/SystemServer.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

/frameworks/base/services/core/java/com/android/server/am/ProcessList.java

/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

/frameworks/base/core/java/android/os/Process.java

/frameworks/base/core/java/android/os/ZygoteProcess.java

/frameworks/base/core/java/android/app/ActivityThread.java

/frameworks/base/core/java/android/app/Activity.java

/frameworks/base/core/java/android/app/ActivityManagerInternal.java

/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl

/frameworks/base/core/java/android/app/ClientTransactionHandler.java

/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java

/frameworks/base/core/java/android/app/Instrumentation.java

/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

从上面的代码路径可以看出,Android10.0中 Activity的相关功能被放到了wm的目录中,在Android9.0中是在am目录中,Google 最终的目的是把activity 和window融合,在Android10中只是做了简单的代码路径的变更,正在的功能还要到后面的版本才能慢慢融合。

1.2 主要代码作用

名称 作用
Instrumentation 负责调用Activity和Application生命周期。
ActivityTaskManagerService 负责Activity管理和调度等工作。ATM是Android10中新增内容
ActivityManagerService 负责管理四大组件和进程,包括生命周期和状态切换。
ActivityTaskManagerInternal 是由ActivityTaskManagerService对外提供的一个抽象类,真正的实现是在 ActivityTaskManagerService#LocalService
ActivityThread 管理应用程序进程中主线程的执行
ActivityStackSupervisor 负责所有Activity栈的管理
TransactionExecutor 主要作用是执行ClientTransaction
ClientLifecycleManager 生命周期的管理调用

二、源码分析

上一节在AMS启动过程中,知道了AMS启动完成前,在systemReady()中会去调用startHomeOnAllDisplays()来启动Launcher,本次就从startHomeOnAllDisplays()函数入口,来看看Launcher是如何被启动起来的。

[ActivityManagerService.java]

java 复制代码
public void systemReady(final Runnable goingCallback, TimingsTraceLog 
traceLog) {
    ...
    //启动Home Activity
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ...
}

Launcher的启动由三部分启动:

SystemServer完成启动Launcher Activity的调用

Zygote()进行Launcher进程的Fork操作

进入ActivityThread的main(),完成最终Launcher的onCreate操作

接下来分别从源码部分来分析这三个启动过程。

2.1 第一阶段SystemServer 启动HomeActivity的调用阶段

调用栈

[ActivityTaskManagerService.java] startHomeOnAllDisplays()

说明:ActivityTaskManagerInternal是 ActivityTaskManagerService的一个抽象类,正在的实现是在ActivityTaskManagerService的LocalService,所以mAtmInternal.startHomeOnAllDisplays()最终调用的是ActivityTaskManagerService的startHomeOnAllDisplays()方法

源码

java 复制代码
public boolean startHomeOnAllDisplays(int userId, String reason) {
          synchronized (mGlobalLock) {
         //一路调用到 RootActivityContainer 的startHomeOnDisplay()方法,参考[2.2]
        return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
     }
}

2.2 [RootActivityContainer.java] startHomeOnDisplay()

说明:在[2.1]中,获取的displayId为DEFAULT_DISPLAY, 首先通过getHomeIntent 来构建一个category为CATEGORY_HOME的Intent,表明是Home Activity;然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合HomeItent的Activity,最终调用startHomeActivity()来启动Activity

源码

java 复制代码
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
    boolean fromHomeKey) {
    ...
     if (displayId == DEFAULT_DISPLAY) {
        //构建一个category为CATEGORY_HOME的Intent,表明是Home Activity,参考[2.2.1]
        homeIntent = mService.getHomeIntent();
        //通过PKMS从系统所用已安装的引用中,找到一个符合HomeItent的Activity参考[2.2.2]
        aInfo = resolveHomeActivity(userId, homeIntent); 
    } 
    ...
    //启动Home Activity,参考[2.3]
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
        displayId);
    return true;
}

2.2.1 [ActivityTaskManagerService.java] getHomeIntent()

说明:构建一个category为CATEGORY_HOME的Intent,表明是Home Activity。

java 复制代码
Intent.CATEGORY_HOME = "android.intent.category.HOME"

这个category会在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity

源码

java 复制代码
Intent getHomeIntent() {
    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    //不是生产模式,add一个CATEGORY_HOME
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    return intent;
}

2.2.2 [RootActivityContainer.java] resolveHomeActivity()

说明:通过Binder跨进程通知PackageManagerService从系统所用已安装的引用中,找到一个符合HomeItent的Activity。

源码

java 复制代码
ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
    final int flags = ActivityManagerService.STOCK_PM_FLAGS;
    final ComponentName comp = homeIntent.getComponent(); //系统正常启动时,component为null
    ActivityInfo aInfo = null;
    ...
        if (comp != null) {
            // Factory test.
            aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
        } else {
            //系统正常启动时,走该流程
            final String resolvedType =
                    homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
            
            //resolveIntent做了两件事:1.通过queryIntentActivities来查找符合HomeIntent需求Activities
            //            2.通过chooseBestActivity找到最符合Intent需求的Activity信息
            final ResolveInfo info = AppGlobals.getPackageManager()
                    .resolveIntent(homeIntent, resolvedType, flags, userId);
            if (info != null) {
                aInfo = info.activityInfo;
            }
        }
    ...
    aInfo = new ActivityInfo(aInfo);
    aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
    return aInfo;
}

2.3 [ActivityStartController.java ] startHomeActivity()

说明:正在的启动Home Activity入口。obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑。另外如果home activity处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复。并将保持这种状态,直到有东西再次触发它。需要进行另一次恢复。

源码

java 复制代码
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
    ....
    //返回一个 ActivityStarter 对象,它负责 Activity 的启动
    //一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑
    //最后执行 ActivityStarter的execute方法
    mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
            .setOutActivity(tmpOutRecord)
            .setCallingUid(0)
            .setActivityInfo(aInfo)
            .setActivityOptions(options.toBundle())
            .execute();  //参考[2.3.1]
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    final ActivityDisplay display =
            mService.mRootActivityContainer.getActivityDisplay(displayId);
    final ActivityStack homeStack = display != null ? display.getHomeStack() : null;

    if (homeStack != null && homeStack.mInResumeTopActivity) {
        //如果home activity 处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复(以避免递归恢复),
        //并将保持这种状态,直到有东西再次触发它。需要进行另一次恢复。
        mSupervisor.scheduleResumeTopActivities();
    }
}

2.3.1 [ActivityStarter.java] execute()

说明:在[2.3]中obtainStarter没有调用setMayWait的方法,因此mRequest.mayWait为false,走startActivity流程。

源码

java 复制代码
int execute() {
    ...
    if (mRequest.mayWait) {
        return startActivityMayWait(...)
    } else {
         return startActivity(...) //参考[2.3.2]
    }
    ...
}

2.3.2 [ActivityStarter.java] startActivity()

说明:延时布局,然后通过startActivityUnchecked()来处理启动标记 flag ,要启动的任务栈等,最后恢复布局。

源码

java 复制代码
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
    ...
    try {
        //延时布局
        mService.mWindowManager.deferSurfaceLayout();
        //调用 startActivityUnchecked ,一路调用到resumeFocusedStacksTopActivities(),参考[2.3.4]
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
    } finally {
        //恢复布局
        mService.mWindowManager.continueSurfaceLayout();
    }
    ...
}

2.3.3 [RootActivityContainer.java] resumeFocusedStacksTopActivities()

说明:获取栈顶的Activity,恢复它

源码

java 复制代码
boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    //如果秒表栈就是栈顶Activity,启动resumeTopActivityUncheckedLocked()
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
        || getTopDisplayFocusedStack() == targetStack)) {
    result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    ...
    if (!resumedOnDisplay) {
        // 获取  栈顶的 ActivityRecord
        final ActivityStack focusedStack = display.getFocusedStack();
        if (focusedStack != null) {
            //最终调用startSpecificActivityLocked(),参考[2.3.4]
            focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
    }
  }
}

2.3.4 [ActivityStackSupervisor.java] startSpecificActivityLocked()

说明:发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁,最终调用到ATM的startProcess()。

源码

java 复制代码
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    ...
    //发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁
    //最终调用到AMS的startProcess(),参考[2.3.5]
    final Message msg = PooledLambda.obtainMessage(
            ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
            r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
    mService.mH.sendMessage(msg);
    ...
}

2.3.5 [ActivityManagerService.java] startProcess()

说明:一路调用Process start(),最终到ZygoteProcess的attemptUsapSendArgsAndGetResult(),用来fork一个新的Launcher的进程。

源码

java 复制代码
public void startProcess(String processName, ApplicationInfo info,
        boolean knownToBeDead, String hostingType, ComponentName hostingName) {
        ..
        //同步操作,避免死锁
        synchronized (ActivityManagerService.this) {
            //调用startProcessLocked,然后到 Process的start,最终到ZygoteProcess的attemptUsapSendArgsAndGetResult()
            //用来fork一个新的Launcher的进程,参考[2.3.6]
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName),
                    false /* allowWhileBooting */, false /* isolated */,
                    true /* keepIfLarge */);
        }
        ...
}

2.3.6 [ZygoteProcess.java] attemptZygoteSendArgsAndGetResult()

说明:通过Socket连接Zygote进程,把之前组装的msg发给Zygote,其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 "android.app.ActivityThread"的main方法。

源码

java 复制代码
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        //传入的zygoteState为openZygoteSocketIfNeeded(),里面会通过abi来检查是第一个zygote还是第二个
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
        final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

        zygoteWriter.write(msgStr);  //把应用进程的一些参数写给前面连接的zygote进程,包括前面的processClass ="android.app.ActivityThread"
        zygoteWriter.flush(); //进入Zygote进程,处于阻塞状态, 参考[2.4]

         //从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
        Process.ProcessStartResult result = new Process.ProcessStartResult();
        result.pid = zygoteInputStream.readInt();
        result.usingWrapper = zygoteInputStream.readBoolean();

        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }

        return result;
    } catch (IOException ex) {
        zygoteState.close();
        Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                + ex.toString());
        throw new ZygoteStartFailedEx(ex);
    }
}

2.4 第二阶段Zygote fork一个Launcher进程的阶段

说明:Zygote的启动过程前面有详细讲到过。SystemServer的AMS服务向启动Home Activity发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。

由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

2.4.1 [ZygoteInit.java] main()

说明:Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher。

源码

java 复制代码
public static void main(String argv[]) {
    ...
    Runnable caller;
    ....
    if (startSystemServer) {
        //Zygote Fork出的第一个进程 SystmeServer
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

        if (r != null) {
            r.run();
            return;
        }
    }
    ...
    //循环等待fork出其他的应用进程,比如Launcher
    //最终通过调用processOneCommand()来进行进程的处理,参考[2.4.2]
    caller = zygoteServer.runSelectLoop(abiList);
    ...
    if (caller != null) {
        caller.run(); //执行返回的Runnable对象,进入子进程
    }
}

2.4.2 [ZygoteConnection.java] processOneCommand()

说明:通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理。

源码

java 复制代码
Runnable processOneCommand(ZygoteServer zygoteServer) {
    int pid = -1;
    ...
    //Fork子进程,得到一个新的pid
    /fork子进程,采用copy on write方式,这里执行一次,会返回两次
    ///pid=0 表示Zygote  fork子进程成功
    //pid > 0 表示子进程 的真正的PID
    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
            parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
            parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
    ...
    if (pid == 0) {
        // in child, fork成功,第一次返回的pid = 0
        ...
        //参考[2.4.3]
        return handleChildProc(parsedArgs, descriptors, childPipeFd,
                parsedArgs.mStartChildZygote);
    } else {
        //in parent
        ...
        childPipeFd = null;
        handleParentProc(pid, descriptors, serverPipeFd);
        return null;
    }
}

2.4.3 [ZygoteConnection.java] handleChildProc()

说明:进行子进程的操作,最终获得需要执行的ActivityThread的main()。

源码

java 复制代码
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
        FileDescriptor pipeFd, boolean isZygote) {
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            // App进程将会调用到这里,执行目标类的main()方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}

zygoteInit 进行一些环境的初始化、启动Binder进程等操作:

java 复制代码
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    RuntimeInit.commonInit(); //初始化运行环境 
    ZygoteInit.nativeZygoteInit(); //启动Binder线程池 
     //调用程序入口函数  
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

把之前传来的"android.app.ActivityThread" 传递给findStaticMain:

java 复制代码
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ...
    // startClass: 如果AMS通过socket传递过来的是 ActivityThread
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

通过反射,拿到ActivityThread的main()方法:

java 复制代码
protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }
    return new MethodAndArgsCaller(m, argv);
}

把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用:

java 复制代码
static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    //调用ActivityThread的main()
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

2.5 第三个阶段,Launcher在自己的进程中进行onCreate等后面的动作

从[2.4]可以看到,Zygote fork出了Launcher的进程,并把接下来的Launcher启动任务交给了ActivityThread来进行,接下来就从ActivityThread main()来分析Launcher的创建过程。

2.5.1 [ActivityThread.java] main()

说明:主线程处理, 创建ActivityThread对象,调用attach进行处理,最终进入Looper循环

源码

java 复制代码
public static void main(String[] args) {
    // 安装选择性的系统调用拦截
    AndroidOs.install();
  ...
  //主线程处理
    Looper.prepareMainLooper();
  ...
  
  //之前SystemServer调用attach传入的是true,这里到应用进程传入false就行
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
  ...
  //一直循环,如果退出,说明程序关闭
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

调用ActivityThread的attach进行处理

java 复制代码
private void attach(boolean system, long startSeq) {
  sCurrentActivityThread = this;
  mSystemThread = system;
  if (!system) {
    //应用进程启动,走该流程
    ...
    RuntimeInit.setApplicationObject(mAppThread.asBinder());
     //获取AMS的本地代理类
    final IActivityManager mgr = ActivityManager.getService();
    try {
      //通过Binder调用AMS的attachApplication方法,参考[2.5.2]
      mgr.attachApplication(mAppThread, startSeq);
    } catch (RemoteException ex) {
      throw ex.rethrowFromSystemServer();
    }
    ...
  } else {
    //通过system_server启动ActivityThread对象
    ...
  }

  // 为 ViewRootImpl 设置配置更新回调,
  当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化
  ViewRootImpl.ConfigChangedCallback configChangedCallback
      = (Configuration globalConfig) -> {
    synchronized (mResourcesManager) {
      ...
    }
  };
  ViewRootImpl.addConfigCallback(configChangedCallback);
}

2.5.2 [ActivityManagerService.java] attachApplication()

说明:清除一些无用的记录,最终调用ActivityStackSupervisor.java的 realStartActivityLocked(),进行Activity的启动

源码

java 复制代码
public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
    //通过Binder获取传入的pid信息
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}
java 复制代码
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
  ...
    //如果当前的Application记录仍然依附到之前的进程中,则清理掉
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }·

    //mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,
    //所以这里的normalMode也为true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
  ...
    //上面说到,这里为true,进入StackSupervisor的attachApplication方法
    //去真正启动Activity
    if (normalMode) {
    ...
      //调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
      //参考[2.5.3]
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
    ...
    }
  ...
    return true;
}

2.5.3 [ActivityStackSupervisor.java] realStartActivityLocked()

说明:真正准备去启动Activity,通过clientTransaction.addCallback把LaunchActivityItem的obtain作为回调参数加进去,再调用ClientLifecycleManager.scheduleTransaction()得到LaunchActivityItem的execute()方法进行最终的执行。

源码:

java 复制代码
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
     // 直到所有的 onPause() 执行结束才会去启动新的 activity
    if (!mRootActivityContainer.allPausedActivitiesComplete()) {
    ...
        return false;
    }
  try {
            // Create activity launch transaction.
            // 添加 LaunchActivityItem
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
      //LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                    r.icicle, r.persistentState, results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                            r.assistToken));

      ...
      // 设置生命周期状态
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            // 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法
      //参考[2.5.4]
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);

        } catch (RemoteException e) {
            if (r.launchFailed) {
                 // 第二次启动失败,finish activity
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }
            // 第一次失败,重启进程并重试
            r.launchFailed = true;
            proc.removeActivity(r);
            throw e;
        }
    } finally {
        endDeferResume();
    }
  ...
    return true;
}

2.5.4 [TransactionExecutor.java] execute()

说明:执行之前realStartActivityLocked()中的clientTransaction.addCallback

源码: [TransactionExecutor.java]

java 复制代码
public void execute(ClientTransaction transaction) {
 ...
    // 执行 callBack,参考上面的调用栈,执行回调方法,
  //最终调用到ActivityThread的handleLaunchActivity()参考[2.5.5]
   executeCallbacks(transaction);

    // 执行生命周期状态
   executeLifecycleState(transaction);
   mPendingActions.clear();
}

2.5.5 [ActivityThread.java] handleLaunchActivity()

说明:主要干了两件事,第一件:初始化WindowManagerGlobal;第二件:调用performLaunchActivity方法

源码:[ActivityThread.java]

java 复制代码
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
  ...
  //初始化WindowManagerGlobal
    WindowManagerGlobal.initialize();
  ...
  //调用performLaunchActivity,来处理Activity,参考[2.5.6]
    final Activity a = performLaunchActivity(r, customIntent);
  ..
    return a;
}

2.5.6 [ActivityThread.java] performLaunchActivity()

说明:获取ComponentName、Context,反射创建Activity,设置Activity的一些内容,比如主题等; 最终调用callActivityOnCreate()来执行Activity的onCreate()方法

源码

java 复制代码
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
     // 获取 ComponentName
    ComponentName component = r.intent.getComponent();
  ...
     // 获取 Context
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
         // 反射创建 Activity
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
    ...
    }

    try {
        // 获取 Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
      ...
      //Activity的一些处理
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback,
                    r.assistToken);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
      ...
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
              // 设置主题
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            // 执行 onCreate()
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
      ...
            r.activity = activity;
        }
    //当前状态为ON_CREATE
        r.setState(ON_CREATE);
    ...
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
    ...
    }
    return activity;
}

callActivityOnCreate先执行activity onCreate的预处理,再去调用Activity的onCreate,最终完成Create创建后的内容处理

java 复制代码
public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity); //activity onCreate的预处理
    activity.performCreate(icicle, persistentState);//执行onCreate()
    postPerformCreate(activity); //activity onCreate创建后的一些信息处理
}

performCreate()主要调用Activity的onCreate()

java 复制代码
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
  ...
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
  ...
}

至此,看到了最熟悉的Activity的onCreate(),Launcher的启动完成,Launcher被真正创建起来。


三、总结

看到onCreate()后,进入到最熟悉的Activity的入口,Launcher的启动告一段落。整个Android的启动流程完整的分析完成。

Launcher的启动经过了三个阶段:

第一个阶段:SystemServer完成启动Launcher Activity的调用

第二个阶段:Zygote()进行Launcher进程的Fork操作

第三个阶段:进入ActivityThread的main(),完成最终Launcher的onCreate操作


四、相关日志

开机启动流程中关于Launcher关键字的log。

c 复制代码
	行  6027: 05-08 18:46:58.502  1504  1504 I SystemServer: StartGestureLauncher
	行  6028: 05-08 18:46:58.502  1504  1504 I SystemServiceManager: Starting com.android.server.GestureLauncherService
	行  6029: 05-08 18:46:58.502  1504  1504 D SystemServerTiming: StartGestureLauncher took to complete: 0ms
	行  6089: 05-08 18:46:58.528  1504  1504 I SystemServer: StartLauncherAppsService
	行  6090: 05-08 18:46:58.528  1504  1504 I SystemServiceManager: Starting com.android.server.pm.LauncherAppsService
	行  6091: 05-08 18:46:58.529  1504  1504 D SystemServerTiming: StartLauncherAppsService took to complete: 1ms
	行  6891: 05-08 18:46:59.180  1504  1504 D SystemServiceManager: onStartUser-0 com.android.server.GestureLauncherService took to complete: 0ms
	行  6912: 05-08 18:46:59.182  1504  1504 D SystemServiceManager: onStartUser-0 com.android.server.pm.LauncherAppsService took to complete: 0ms
	行  7848: 05-08 18:46:59.809   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: bindService is called for service : com.android.launcher3/com.android.quickstep.TouchInteractionService and for client com.android.systemui
	行  7850: 05-08 18:46:59.809   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: total connections for service : com.android.launcher3/com.android.quickstep.TouchInteractionServiceare :1
	行  7879: 05-08 18:46:59.844  1504  1649 I am_proc_start: [0,2435,10112,com.android.launcher3,service,{com.android.launcher3/com.android.quickstep.TouchInteractionService}]
	行  7880: 05-08 18:46:59.844  1504  1649 I ActivityManager: Start proc 2435:com.android.launcher3/u0a112 for service {com.android.launcher3/com.android.quickstep.TouchInteractionService}
	行  7931: 05-08 18:46:59.905  1504  2231 I am_proc_bound: [0,2435,com.android.launcher3]
	行  7947: 05-08 18:46:59.912   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: startService() is called for servicecom.android.launcher3/com.android.quickstep.TouchInteractionService
	行  8237: 05-08 18:47:00.075  2435  2435 W ContextImpl: Failed to ensure /data/user/0/com.android.launcher3/cache: mkdir failed: ENOENT (No such file or directory)
	行  8368: 05-08 18:47:00.140  1504  1504 V NotificationListeners: enabling notification listener for 0: ComponentInfo{com.android.launcher3/com.android.launcher3.notification.NotificationListener}
	行  8370: 05-08 18:47:00.141  1504  1504 V NotificationListeners: binding: Intent { act=android.service.notification.NotificationListenerService cmp=com.android.launcher3/.notification.NotificationListener (has extras) }
	行  8371: 05-08 18:47:00.141  1504  1504 W ActivityManager: Unable to start service Intent { act=android.service.notification.NotificationListenerService cmp=com.android.launcher3/.notification.NotificationListener } U=0: not found
	行  8372: 05-08 18:47:00.141  1504  1504 W NotificationListeners: Unable to bind notification listener service: Intent { act=android.service.notification.NotificationListenerService cmp=com.android.launcher3/.notification.NotificationListener (has extras) } in user 0
	行 13479: 05-08 18:47:03.025  1504  1648 D SystemServiceManager: onUnlockUser-0 com.android.server.GestureLauncherService took to complete: 0ms
	行 13491: 05-08 18:47:03.026  1504  1648 D SystemServiceManager: onUnlockUser-0 com.android.server.pm.LauncherAppsService took to complete: 0ms
	行 13593: 05-08 18:47:03.068  1504  1648 V ActivityManager: Installing ContentProviderInfo{name=com.android.launcher3 className=com.android.quickstep.LauncherSearchIndexablesProvider}
	行 13594: 05-08 18:47:03.068  1504  1648 V ActivityManager: Installing ContentProviderInfo{name=com.android.launcher3.settings className=com.android.launcher3.LauncherProvider}
	行 13734: 05-08 18:47:03.171  1504  3109 I ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.launcher3/.Launcher} from uid 0
	行 13771: 05-08 18:47:03.228  1504  3109 I am_create_activity: [0,91065182,970,com.android.launcher3/.Launcher,android.intent.action.MAIN,NULL,NULL,268435712]
	行 13800: 05-08 18:47:03.246  1504  1504 V NotificationListeners: enabling notification listener for 0: ComponentInfo{com.android.launcher3/com.android.launcher3.notification.NotificationListener}
	行 13801: 05-08 18:47:03.246  1504  1504 V NotificationListeners: binding: Intent { act=android.service.notification.NotificationListenerService cmp=com.android.launcher3/.notification.NotificationListener (has extras) }
	行 13811: 05-08 18:47:03.249   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: unbindService is called for service : com.android.launcher3/com.android.quickstep.TouchInteractionService and for client com.android.systemui
	行 13812: 05-08 18:47:03.249   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: size of service connections for service: com.android.launcher3/com.android.quickstep.TouchInteractionServiceafter removal is 0
	行 13814: 05-08 18:47:03.250   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: destroyService is called for service : com.android.launcher3/com.android.quickstep.TouchInteractionService
	行 13867: 05-08 18:47:03.271   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: bindService is called for service : com.android.launcher3/.notification.NotificationListener and for client system
	行 13868: 05-08 18:47:03.271   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: total connections for service : com.android.launcher3/.notification.NotificationListenerare :1
	行 13877: 05-08 18:47:03.277   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: startService() is called for servicecom.android.launcher3/.notification.NotificationListener
	行 13887: 05-08 18:47:03.283   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: bindService is called for service : com.android.launcher3/com.android.quickstep.TouchInteractionService and for client com.android.systemui
	行 13888: 05-08 18:47:03.284   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: total connections for service : com.android.launcher3/com.android.quickstep.TouchInteractionServiceare :1
	行 13890: 05-08 18:47:03.284  1504  1632 I ActivityTaskManager: The Process com.android.launcher3 Already Exists in BG. So sending its PID: 2435
	行 13892: 05-08 18:47:03.287  1504  1632 I am_restart_activity: [0,91065182,970,com.android.launcher3/.Launcher]
	行 13901: 05-08 18:47:03.288  1504  1632 I am_set_resumed_activity: [0,com.android.launcher3/.Launcher,minimalResumeActivityLocked]
	行 13903: 05-08 18:47:03.289  1504  1632 I am_add_to_stopping: [0,91065182,com.android.launcher3/.Launcher,makeInvisible]
	行 13906: 05-08 18:47:03.290  1504  1632 I am_pause_activity: [0,91065182,com.android.launcher3/.Launcher,userLeaving=false]
	行 13930: 05-08 18:47:03.309   722   761 I /vendor/bin/hw/vendor.qti.hardware.servicetracker@1.1-service: startService() is called for servicecom.android.launcher3/com.android.quickstep.TouchInteractionService
	行 13931: 05-08 18:47:03.309  1504  1632 I sysui_multi_action: [757,1144,758,8,806,com.android.launcher3,871,com.android.launcher3.Launcher]
	行 14061: 05-08 18:47:03.504  1504  1504 V NotificationListeners: 0 notification listener service connected: ComponentInfo{com.android.launcher3/com.android.launcher3.notification.NotificationListener}
	行 14132: 05-08 18:47:03.596  2435  2435 V Launcher: LauncherAppState initiated
	行 14803: 05-08 18:47:03.791  1504  1632 W ActivityTaskManager: Activity top resumed state loss timeout for ActivityRecord{56d8b5e u0 com.android.launcher3/.Launcher t970}
	行 14804: 05-08 18:47:03.791  1504  1632 W ActivityTaskManager: Activity pause timeout for ActivityRecord{56d8b5e u0 com.android.launcher3/.Launcher t970}
	行 14831: 05-08 18:47:03.799  1504  1632 I am_stop_activity: [0,91065182,com.android.launcher3/.Launcher]
	行 15393: 05-08 18:47:04.232  2435  2435 I am_on_create_called: [0,com.android.launcher3.Launcher,performCreate]
	行 15400: 05-08 18:47:04.242  2435  2435 I am_on_start_called: [0,com.android.launcher3.Launcher,handleStartActivity]
	行 15401: 05-08 18:47:04.243  2435  2435 I am_on_resume_called: [0,com.android.launcher3.Launcher,RESUME_ACTIVITY]
	行 15408: 05-08 18:47:04.255  2435  2435 I am_on_top_resumed_gained_called: [0,com.android.launcher3.Launcher,topStateChangedWhenResumed]
	行 15409: 05-08 18:47:04.255  2435  2435 I am_on_top_resumed_lost_called: [0,com.android.launcher3.Launcher,topStateChangedWhenResumed]
	行 15410: 05-08 18:47:04.255  2435  2435 I am_on_paused_called: [0,com.android.launcher3.Launcher,performPause]
	行 15411: 05-08 18:47:04.256  1504  3100 I am_failed_to_pause: [0,91065182,com.android.launcher3/.Launcher,(none)]
	行 15420: 05-08 18:47:04.268  2435  2435 I am_on_stop_called: [0,com.android.launcher3.Launcher,STOP_ACTIVITY_ITEM]
	行 16064: 05-08 18:47:05.573  1504  3106 I am_set_resumed_activity: [0,com.android.launcher3/.Launcher,resumeTopActivityInnerLocked]
	行 16065: 05-08 18:47:05.574  1504  3106 I am_resume_activity: [0,91065182,970,com.android.launcher3/.Launcher]
	行 16070: 05-08 18:47:05.590  2435  2435 I am_on_restart_called: [0,com.android.launcher3.Launcher,performRestartActivity]
	行 16071: 05-08 18:47:05.591  2435  2435 I am_on_start_called: [0,com.android.launcher3.Launcher,handleStartActivity]
	行 16072: 05-08 18:47:05.592  2435  2435 I am_on_resume_called: [0,com.android.launcher3.Launcher,RESUME_ACTIVITY]
	行 16073: 05-08 18:47:05.592  2435  2435 I am_on_top_resumed_gained_called: [0,com.android.launcher3.Launcher,topWhenResuming]

相关推荐
拭心11 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王13 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡14 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道14 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库15 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道15 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe16 小时前
Android Hook - 动态加载so库
android
居居飒16 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He19 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗19 小时前
Android笔试面试题AI答之Android基础(1)
android