当前位置: 首页 > news >正文

Android 10.0 Launcher 启动流程

在前面SystemUI启动流程中说到,在SystemServer中会去启动各种系统服务,这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前,系统四大组件的启动都是在ActivityManagerService中,在android10中,单独抽出了一个ActivityTaskManagerService,主要负责Activity的管理和调度。这里先来看下ActivityManagerService服务的启动:
frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {... ...// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");// TODO: Might need to move after migration to WM.ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mWindowManagerGlobalLock = atm.getGlobalLock();traceEnd();... ...
}

当SystemServiceManager调用 startService() 时,就会通过反射去创建传进去的class,然后在调用创建对象的 onStart() 方法,这里就是去初始化ActivityTaskManagerService和ActivityManagerService对象,并不会去启动launcher,而且系统服务启动分为三块:
frameworks/base/services/java/com/android/server/SystemServer.java

startBootstrapServices();   // 启动引导服务
startCoreServices();        // 启动核心服务
startOtherServices();       // 启动其他服务

在startOtherServices()中可以看到:
frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {... ...// We now tell the activity manager it is okay to run third party// code.  It will call back into us once it has gotten to the state// where third party code can really run (but before it has actually// started launching the initial applications), for us to complete our// initialization.mActivityManagerService.systemReady(() -> {... ...});
}

这就说明在所有服务初始化完成后,在这里会通知ActivityManagerService的systemReady()启动 launcher 的进程。
下面一起来看 launcher 是如何被启动起来的:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {... ...mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");... ...mAtmInternal.resumeTopActivities(false /* scheduleIdle */);... ...
}

mAtmInternal类型是ActivityTaskManagerInternal,这是一个抽象类,其实现是ActivityTaskManagerService的内部类LocalService:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

final class LocalService extends ActivityTaskManagerInternal {... ...@Overridepublic boolean startHomeOnAllDisplays(int userId, String reason) {synchronized (mGlobalLock) {return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);}}... ...@Overridepublic void resumeTopActivities(boolean scheduleIdle){synchronized (mGlobalLock){mRootActivityContainer.resumeFocusedStacksTopActivities();if(scheduleIdle){mStackSupervisor.scheduleIdleLocked();}}}... ...
}

这里的mRootActivityContainer类型是RootActivityContainer,按照文档上的说明,这是一个临时类,主要是将ActivityStackSupervisor.java中的一部分逻辑分离出来,在android11中,这个类就已经找不到了。替换成了RootWindowContainer,这里我们跟进 mRootActivityContainer.startHomeOnAllDisplays() 方法看,最终会调用到:startHomeOnDisplay() :
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

boolean startHomeOnDisplay(int userId,String reason,int displayId,boolean allowInstrumenting,boolean fromHomeKey){// Fallback to top focused display if the displayId is invalid.if(displayId==INVALID_DISPLAY){displayId=getTopDisplayFocusedStack().mDisplayId;}Intent homeIntent=null;ActivityInfo aInfo=null;if(displayId==DEFAULT_DISPLAY){//拿到需要启动launcher的intent,通过resolveHomeActivity解析出需要启动的ActivityhomeIntent=mService.getHomeIntent();aInfo=resolveHomeActivity(userId,homeIntent);}else if(shouldPlaceSecondaryHomeOnDisplay(displayId)){Pair<ActivityInfo, Intent> info=resolveSecondaryHomeActivity(userId,displayId);aInfo=info.first;homeIntent=info.second;}if(aInfo==null||homeIntent==null){return false;}if(!canStartHomeOnDisplay(aInfo,displayId,allowInstrumenting)){return false;}// Updates the home component of the intent.homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName,aInfo.name));homeIntent.setFlags(homeIntent.getFlags()|FLAG_ACTIVITY_NEW_TASK);// Updates the extra information of the intent.if(fromHomeKey){homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY,true);}// Update the reason for ANR debugging to verify if the user activity is the one that// actually launched.final String myReason=reason+":"+userId+":"+UserHandle.getUserId(aInfo.applicationInfo.uid)+":"+displayId;mService.getActivityStartController().startHomeActivity(homeIntent,aInfo,myReason,displayId);return true;
}

这里可以分为两步看:
  1、通过ActivityTaskManagerService的getHomeIntent()获取到需要启动的intent,在通过resolveHomeActivity()解析出需要启动Activity的信息,
  2、mService.getActivityStartController()获取到的是ActivityStartController,这个类的主要作用是用于控制委派启动的Activity。
先来看下ActivityTaskManagerService的getHomeIntent() :
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

    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;}

注意看 intent.addCategory(Intent.CATEGORY_HOME) ,这个代表的就是要启动Activity的意图,通常来说,整个系统的只会有一个应用会在清单文件中配置CATEGORY_HOME,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪个作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用启动。(这个 CATEGORY_HOME 配置,说白了就只有 launcher 程序才会有)。
回到主线,接着看mService.getActivityStartController().startHomeActivity() :
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,TaskDisplayArea taskDisplayArea) {final ActivityOptions options = ActivityOptions.makeBasic();options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);if (!ActivityRecord.isResolverActivity(aInfo.name)) {// The resolver activity shouldn't be put in home stack because when the foreground is// standard type activity, the resolver activity should be put on the top of current// foreground instead of bring home stack to front.options.setLaunchActivityType(ACTIVITY_TYPE_HOME);}final int displayId = taskDisplayArea.getDisplayId();options.setLaunchDisplayId(displayId);options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken.toWindowContainerToken());// The home activity will be started later, defer resuming to avoid unneccerary operations// (e.g. start home recursively) when creating home stack.mSupervisor.beginDeferResume();final ActivityStack homeStack;try {// Make sure home stack exists on display area.homeStack = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);} finally {mSupervisor.endDeferResume();}mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason).setOutActivity(tmpOutRecord).setCallingUid(0).setActivityInfo(aInfo).setActivityOptions(options.toBundle()).execute();mLastHomeActivityStartRecord = tmpOutRecord[0];if (homeStack.mInResumeTopActivity) {// 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();}}/*** @return A starter to configure and execute starting an activity. It is valid until after*         {@link ActivityStarter#execute} is invoked. At that point, the starter should be*         considered invalid and no longer modified or used.*/ActivityStarter obtainStarter(Intent intent, String reason) {return mFactory.obtain().setIntent(intent).setReason(reason);}

这里主要是先获取一个ActivityStarter(主要用于启动Activity),然后把需要的参数设置进去,最后再调用它的ActivityStarter.execute()方法:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

int execute() {try {... ...final LaunchingState launchingState;synchronized (mService.mGlobalLock) {final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);// 通过ActivityMetricsLogger.notifyActivityLaunching创建LaunchingState并记录创建Activity开始的时间launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mRequest.intent, caller);}... ...// 执行启动请求res = executeRequest(mRequest);... ...// Notify ActivityMetricsLogger that the activity has launched.// ActivityMetricsLogger will then wait for the windows to be drawn and populate// WaitResult.// 通过ActivityMetricsLogger.notifyActivityLaunched记录Activity启动完成的时间mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,mLastStartActivityRecord);// 同时将Request.waitResult添加到ActivityStackSupervisor的mWaitingActivityLaunched中,等待窗口绘制完成return getExternalResult(mRequest.waitResult == null ? res: waitForResult(res, mLastStartActivityRecord));        } finally {onExecutionComplete();}}

通过上面代码我们知道,启动是在 executeRequest() 方法里:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

    private int executeRequest(Request request) {... ...//调用 startActivityUncheckedmLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,restrictedBgActivity, intentGrants);return mLastStartActivityResult;}

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

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, Task inTask,boolean restrictedBgActivity, NeededUriGrants intentGrants) {int result = START_CANCELED;... ...try {//延时布局mService.deferWindowLayout();//执行startActivityInnerresult = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);} finally {//恢复布局mService.continueWindowLayout();}... ...return result;}

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

int startActivityInner() { ... ...if (mDoResume) {//ActivityRecord 记录着 Activity 信息final ActivityRecord topTaskActivity =mStartActivity.getTask().topRunningActivityLocked();if (!mTargetStack.isTopActivityFocusable()|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()&& mStartActivity != topTaskActivity)) {mTargetStack.getDisplay().mDisplayContent.executeAppTransition();} else {//执行resumeFocusedStacksTopActivitiesmRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);}}... ...return START_SUCCESS;}

RootWindowContainer.resumeFocusedStacksTopActivities()
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {... ...//如果是栈顶Activity,启动resumeTopActivityUncheckedLockedif (targetStack != null && (targetStack.isTopStackInDisplayArea()|| getTopDisplayFocusedStack() == targetStack)) {result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}... ...if (!resumedOnDisplay) {//获取栈顶的 ActivityRecordfinal ActivityStack focusedStack = display.getFocusedStack();if (focusedStack != null) {//执行resumeTopActivityUncheckedLockedresult |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);}else if (targetStack == null) {result |= resumeHomeActivity(null /* prev */, "no-focusable-task",display.getDefaultTaskDisplayArea());}}return result;
}

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

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {if (mInResumeTopActivity) {// Don't even start recursing.return false;}boolean result = false;try {mInResumeTopActivity = true;// 执行 resumeTopActivityInnerLocked,// 最终调用到 ActivityStackSupervisor.startSpecificActivity()result = resumeTopActivityInnerLocked(prev, options);final ActivityRecord next = topRunningActivity(true /* focusableOnly */);if (next == null || !next.canTurnScreenOn()) {checkReadyForSleep();}} finally {mInResumeTopActivity = false;}return result;}

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

    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {// Is this activity's application already running?final WindowProcessController wpc =mService.getProcessController(r.processName, r.info.applicationInfo.uid);boolean knownToBeDead = false;//进程存在if (wpc != null && wpc.hasThread()) {try {//真正启动Activity方法realStartActivityLocked(r, wpc, andResume, checkConfig);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting activity "+ r.intent.getComponent().flattenToShortString(), e);}// If a dead object exception was thrown -- fall through to// restart the application.knownToBeDead = true;}r.notifyUnknownVisibilityLaunchedForKeyguardTransition();final boolean isTop = andResume && r.isTopRunningActivity();//进程不存在 mService =ATMSmService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");}

startSpecificActivity() 这个方法是关键方法,如果进程已经存在直接执行 realStartActivityLocked 去启动 Activity,进程不存在则通过AMS去创建 Socket,然后通知 Zygote 去 fork 进程。由于这里第一次创建,所以会走到 startProcessAsync() 。
Launcher启动流程调用栈:

创建Socket建立连接
ActivityTaskManagerService.startProcessAsync()
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

    void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,String hostingType) {try {if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"+ activity.processName);}// Post message to start process to avoid possible deadlock of calling into AMS with the// ATMS lock held.final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,isTop, hostingType, activity.intent.getComponent());mH.sendMessage(m);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}}

通过handler发消息执行ActivityManagerInternal.startProcess() ,内部又转调用ActivityManagerService.startProcessLocked() :
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, boolean knownToBeDead, int intentFlags,HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,boolean isolated, boolean keepIfLarge) {return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,keepIfLarge, null /* ABI override */, null /* entryPoint */,null /* entryPointArgs */, null /* crashHandler */);
}

mProcessList类型是ProcessList,这是一个进程管理类,描述了进程的adj值,当系统资源吃紧时,就会根据这里描述的adj去判断杀死哪个应用来释放资源,可以通过adb shell dumpsys meminfo来查看当前所有进程的分类情况,接着来看下ProcessList.startProcessLocked():
frameworks/base/services/core/java/com/android/server/am/ProcessList.java

    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {ProcessRecord app;... ...checkSlow(startTime, "startProcess: stepping in to startProcess");final boolean success = startProcessLocked(app, hostingRecord, abiOverride);checkSlow(startTime, "startProcess: done starting proc!");return success ? app : null;}boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,boolean disableHiddenApiChecks, boolean mountExtStorageFull,String abiOverride) {... ...try {... ...// Start the process.  It will either succeed and return a result containing// the PID of the new process, or else throw a RuntimeException.final String entryPoint = "android.app.ActivityThread";return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,startTime);} catch (RuntimeException e) {Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);// Something went very wrong while trying to start this process; one// common case is when the package is frozen due to an active// upgrade. To recover, clean up any active bookkeeping related to// starting this process. (We already invoked this method once when// the package was initially frozen through KILL_APPLICATION_MSG, so// it doesn't hurt to use it again.)mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),false, false, true, false, false, app.userId, "start failure");return false;}}boolean startProcessLocked(HostingRecord hostingRecord,String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {... ...final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);... ...}private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {try {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +app.processName);checkSlow(startTime, "startProcess: asking zygote to start proc");final Process.ProcessStartResult startResult;if (hostingRecord.usesWebviewZygote()) {... ...} else if (hostingRecord.usesAppZygote()) {final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);startResult = appZygote.getProcess().start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, null, app.info.packageName,/*useUsapPool=*/ false,new String[] {PROC_START_SEQ_IDENT + app.startSeq});} else {... ...}checkSlow(startTime, "startProcess: returned from zygote!");return startResult;} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}

这里有几个我们需要关注的点,一个是第二个方法定义的entryPoint=“android.app.ActivityThread”,这个就是后面创建进程时会通过反射调用到的类,再来看最后一个方法,这里会执行else if语句,也就是执行ZygoteProcess的start()方法。最终到 ZygoteProcess 的attemptUsapSendArgsAndGetResult 通过 Socket 通信,fork 一个新的 Launcher 进程,调用过程如图:

ZygoteProcess.attemptZygoteSendArgsAndGetResult()
frameworks/base/core/java/android/os/ZygoteProcess.java

    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {try {final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;zygoteWriter.write(msgStr);把应用进程的一些参数写给前面连接的zygote进程zygoteWriter.flush();//进入Zygote进程,处于阻塞状态//从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象Process.ProcessStartResult result = new Process.ProcessStartResult();result.pid = zygoteInputStream.readInt();result.usingWrapper = zygoteInputStream.readBoolean();return result;} catch (IOException ex) {zygoteState.close();}}

Zygote进程处理
ZygoteInit.main
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {Runnable caller;if (startSystemServer) {//Zygote Fork出的第一个进程 SystmeServerRunnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);if (r != null) {r.run();return;}}//循环等待fork出其他的应用进程,比如Launchercaller = zygoteServer.runSelectLoop(abiList);...if (caller != null) {caller.run(); //执行runSelectLoop返回的Runnable对象,进入子进程}
}

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

Runnable runSelectLoop(String abiList) {while (true) {int pollReturnValue;try {//epoll机制 循环pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);} catch (ErrnoException ex) {throw new RuntimeException("poll failed", ex);}...//来了消息后,调用processOneCommand()来进行进程的处理final Runnable command =  connection.processOneCommand(this);} 
}

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

Runnable processOneCommand(ZygoteServer zygoteServer) {//fork进程,得到新进程pid//pid=0 表示Zygote  fork子进程成功//pid > 0 表示子进程 的真正的PIDpid = 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.mIsTopApp,parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);try {//fork成功,第一次返回的pid = 0if (pid == 0) {return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);} else {handleParentProc(pid, serverPipeFd);return null;}
}

ZygoteConnection.handleChildProc
这里主要执行到 ZygoteInit.zygoteInit,zygoteInit 进行一些环境的初始化、启动Binder进程等操作,最终反射执行 ActivityThread.main
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

    private Runnable handleChildProc(ZygoteArguments parsedArgs,FileDescriptor pipeFd, boolean isZygote) {closeSocket();Zygote.setAppProcessName(parsedArgs, TAG);if (!isZygote) {//App进程将会调用到这里,最终反射执行ActivityThread.mainreturn ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, null /* classLoader */);} else {return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */);}}

Zygote进程调用栈:

ActivityThread中处理
Zygote fork出了 Launcher 的进程,并把接下来的 Launcher 启动任务交给了 ActivityThread 来进行,接下来我们就从 ActivityThread.main方法来分析 Launcher 的创建过程。
frameworks/base/core/java/android/app/ActivityThread.java

    public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");... ...//创建主线程LooperLooper.prepareMainLooper();... ...ActivityThread thread = new ActivityThread();//执行attach... ...thread.attach(false, startSeq);//开启循环... ...Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}

这里就是android层面划分为一个应用进程的开始,初始化一个looper,也就是android中说的主线程,并开始looper循环,这里调用到了ActivitThread.attach() :
frameworks/base/core/java/android/app/ActivityThread.java

    private void attach(boolean system, long startSeq) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {... ...// 这里会拿到ActivityManagerService的代理final IActivityManager mgr = ActivityManager.getService();try {//应用的句柄发给AMS,从而使AMS可以管理新进程mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}... ...} else {// 在前面讲Zygote进程的时候,里面创建ActivityThread就会执行到这里}//当系统配置发生变更时会执行这个回调ViewRootImpl.ConfigChangedCallback configChangedCallback= (Configuration globalConfig) -> {... ...};ViewRootImpl.addConfigCallback(configChangedCallback);}

这里会执行if语句里面的内容,mAppThread的类型是ApplicationThread,这个类的主要作用是在ActivityManagerService中回调回ActivityThread中来,mgr是ActivityManagerService的代理,在执行它的ActivityManagerService.attachApplication() 方法:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    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);Binder.restoreCallingIdentity(origId);}}

ActivityManagerService.attachApplicationLocked()
调用AMS的 attachApplication(),最终层层调用到 ActivityStackSupervisor 的 realStartActivityLocked,真正准备去启动Activity。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    private final boolean attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) {... ...//这里会去调用ActivityThrea的bindApplication(),也就是会去创建Applicationthread.bindApplication(... ...)... ...//如果当前的Application记录仍然依附到之前的进程中,则清理掉if (app.thread != null) {handleAppDiedLocked(app, true, true);}... ...// See if the top visible activity is waiting to run in this process...if (normalMode) {try {//调用ActivityTaskManagerService的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}... ...}

这里通过AMS最终会调用到ActivityStackSupervisor.realStartActivityLocked():
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {//确保所有的Activity执行了onPause才会往下继续执行if (!mRootActivityContainer.allPausedActivitiesComplete()) {// While there are activities pausing we skipping starting any new activities until// pauses are complete. NOTE: that we also do this for activities that are starting in// the paused state because they will first be resumed then paused on the client side.if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,"realStartActivityLocked: Skipping start of r=" + r+ " some activities pausing...");return false;}... ...try {... ...try{... ...// Create activity launch transaction.final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);final DisplayContent dc = r.getDisplay().mDisplayContent;//在回调序列的末尾添加一条消息clientTransaction.addCallback(LaunchActivityItem.obtain(... ...));// Set desired final state.final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());} else {lifecycleItem = PauseActivityItem.obtain();}//添加最后执行的生命周期状态clientTransaction.setLifecycleStateRequest(lifecycleItem);// 这里其实就是执行ClientTransaction的schedule()方法mService.getLifecycleManager().scheduleTransaction(clientTransaction);... ...} catch (RemoteException e) {if (r.launchFailed) {// 第二次启动失败,finish activity并放弃启动Slog.e(TAG, "Second failure launching "+ r.intent.getComponent().flattenToShortString() + ", giving up", e);proc.appDied();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;}

ActivityThread调用栈:

小结

至此已经走到 realStartActivityLocked,接下来就是 Activity 的启动流程,Activity 启动下篇文章会单独分析。总结一下 Launcher 启动流程,Launcher的启动经过了三个阶段:
  1、SystemServer 创建AMS和ATMS,通过 SystemReady 进入 LauncherActivity 的调用
  2、Zygote 进程 fork 出 Launcher 进程,通过 Socket 进行通信
  3、进入 ActivityThread 的处理,完成 Launcher 的 Acitivty 启动

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 开源消息队列比较
  • 【前端 15】Vue生命周期
  • 数据库实验:SQL Server基本表单表查询
  • SpringBoot集成Sharding-JDBC实现分库分表
  • 【计算机网络】TCP协议详解
  • linux环境下重新编译opencv的安卓动态链接库opencv_java4.so文件
  • TransmittableThreadLocal跟InheritableThreadLocal使用
  • 搭建自己的金融数据源和量化分析平台(一):系统架构设计
  • 【初阶数据结构篇】顺序表的实现(赋源码)
  • Mysql中DML的几种操作
  • 【React】详解“最新”和“最热”切换与排序
  • 实战解读:Llama Guard 3 Prompt Guard
  • 【机器学习】探索图神经网络 (GNNs): 揭秘图结构数据处理的未来
  • 软件环境安装-通过Docker安装rabbitmq
  • 在Android开发中,如何优化onCreate()和onResume()方法以提高应用性能?
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • 345-反转字符串中的元音字母
  • E-HPC支持多队列管理和自动伸缩
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • gops —— Go 程序诊断分析工具
  • Gradle 5.0 正式版发布
  • happypack两次报错的问题
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • JAVA_NIO系列——Channel和Buffer详解
  • Javascript弹出层-初探
  • JS实现简单的MVC模式开发小游戏
  • JWT究竟是什么呢?
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • mysql外键的使用
  • PHP变量
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 不上全站https的网站你们就等着被恶心死吧
  • 从PHP迁移至Golang - 基础篇
  • 关于springcloud Gateway中的限流
  • 讲清楚之javascript作用域
  • 聊聊directory traversal attack
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • AI算硅基生命吗,为什么?
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • 国内开源镜像站点
  • ​插件化DPI在商用WIFI中的价值
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #define
  • #laravel部署安装报错loadFactoriesFrom是undefined method #
  • #Lua:Lua调用C++生成的DLL库
  • #大学#套接字
  • #控制台大学课堂点名问题_课堂随机点名
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (3)llvm ir转换过程
  • (4.10~4.16)
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (规划)24届春招和25届暑假实习路线准备规划