Launcher进程启动流程

在分析ActivityManagerService启动流程的时候说过,ActivityManagerService启动完成后,会调用ActivityTaskManagerService启动HomeActivity并启动Launcher进程

    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
  • ActivityTaskManagerService.LocalService -> startHomeOnAllDisplays(currentUserId, “systemReady”)
    @Overridepublic boolean startHomeOnAllDisplays(int userId, String reason) {synchronized (mGlobalLock) {return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);}}
  • RootActivityContainer -> startHomeOnAllDisplays
    boolean startHomeOnAllDisplays(int userId, String reason) {boolean homeStarted = false;for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {final int displayId = mActivityDisplays.get(i).mDisplayId;homeStarted |= startHomeOnDisplay(userId, reason, displayId);}return homeStarted;}

根据注释mActivityDisplays是一个List,包含多个Activity,按照Z轴排序,最后一个entry表示显示在最上面的Activity。

  • RootActivityContainer ->startHomeOnDisplay()
    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) {homeIntent = 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;}

在上面的方法中,通过ActivityTaskManagerService获取HomeIntent,即intent中category为android.intent.category.HOME的Activity。代码中可以看到是以FLAG_ACTIVITY_NEW_TASK方式启动。

  • ActivityStartController -> startHomeActivity
    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {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);}options.setLaunchDisplayId(displayId);mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason).setOutActivity(tmpOutRecord).setCallingUid(0).setActivityInfo(aInfo).setActivityOptions(options.toBundle()).execute();mLastHomeActivityStartRecord = tmpOutRecord[0];final ActivityDisplay display =mService.mRootActivityContainer.getActivityDisplay(displayId);final ActivityStack homeStack = display != null ? display.getHomeStack() : null;if (homeStack != null && 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();}}

接下来就是Activity的启动流程。ActivityStarter.execute() -> startActivityMayWait()-> startActivity()->…->startActivityUnchecked()
在startActivityUnchecked中,针对启动模式进行了处理,然后调用RootContainerActivity的resumeFocusedStacksTopActivities方法
RootContainerActivity.resumeFocusedStacksTopActivities() -> ActivityStack.resumeTopActivityUncheckedLocked-> ActivityStack.resumeTopActivityInnerLocked() -> ActivityStackSupervisor.startSpecificActivityLocked()

    void startSpecificActivityLocked(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 {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;}// Suppress transition until the new activity becomes ready, otherwise the keyguard can// appear for a short amount of time before the new process with the new activity had the// ability to set its showWhenLocked flags.if (getKeyguardController().isKeyguardLocked()) {r.notifyUnknownVisibilityLaunched();}try {if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"+ r.processName);}// Post message to start process to avoid possible deadlock of calling into AMS with the// ATMS lock held.final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());mService.mH.sendMessage(msg);} finally {Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}}

如果应用已经在运行,则直接运行realStartActivityLocked()。此种情况对应于在应用中Activity启动另一个Activity。
启动Launcher的Activity时,或者启动其他应用的首个Activity时,此时需要走下面的代码。

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

通过PooledLambda获取的message,使用lambda表达式传入startProcess方法,在obtainMessage被封装在PoledLambdaImpl中,PoledLambdaImpl实现了Runnable方法,在obtainMessage方法中设置为Message的callback,也就是说最后通过sendMessage发出去后,实际执行的是startProcess方法。

    @Overridepublic void startProcess(String processName, ApplicationInfo info,boolean knownToBeDead, String hostingType, ComponentName hostingName) {try {if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"+ processName);}synchronized (ActivityManagerService.this) {startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,new HostingRecord(hostingType, hostingName),false /* allowWhileBooting */, false /* isolated */,true /* keepIfLarge */);}} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}

startProcess通过binder跨进程调用ActivityManagerService.LocalService中的startProcess,然后调用startProcessLocked -> mProcessList.startProcessLocked()->…->ProcessList.startProcess()->Process.start()->ZygoteProcess.start()->startViaZygote()

    private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,@Nullable final String niceName,final int uid, final int gid,@Nullable final int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,@Nullable String seInfo,@NonNull String abi,@Nullable String instructionSet,@Nullable String appDataDir,@Nullable String invokeWith,boolean startChildZygote,@Nullable String packageName,boolean useUsapPool,@Nullable String[] extraArgs)throws ZygoteStartFailedEx {ArrayList<String> argsForZygote = new ArrayList<>();// --runtime-args, --setuid=, --setgid=,// and --setgroups= must go firstargsForZygote.add("--runtime-args");argsForZygote.add("--setuid=" + uid);argsForZygote.add("--setgid=" + gid);argsForZygote.add("--runtime-flags=" + runtimeFlags);if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {argsForZygote.add("--mount-external-default");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {argsForZygote.add("--mount-external-read");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {argsForZygote.add("--mount-external-write");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {argsForZygote.add("--mount-external-full");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {argsForZygote.add("--mount-external-installer");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {argsForZygote.add("--mount-external-legacy");}argsForZygote.add("--target-sdk-version=" + targetSdkVersion);// --setgroups is a comma-separated listif (gids != null && gids.length > 0) {StringBuilder sb = new StringBuilder();sb.append("--setgroups=");int sz = gids.length;for (int i = 0; i < sz; i++) {if (i != 0) {sb.append(',');}sb.append(gids[i]);}argsForZygote.add(sb.toString());}if (niceName != null) {argsForZygote.add("--nice-name=" + niceName);}if (seInfo != null) {argsForZygote.add("--seinfo=" + seInfo);}if (instructionSet != null) {argsForZygote.add("--instruction-set=" + instructionSet);}if (appDataDir != null) {argsForZygote.add("--app-data-dir=" + appDataDir);}if (invokeWith != null) {argsForZygote.add("--invoke-with");argsForZygote.add(invokeWith);}if (startChildZygote) {argsForZygote.add("--start-child-zygote");}if (packageName != null) {argsForZygote.add("--package-name=" + packageName);}argsForZygote.add(processClass);if (extraArgs != null) {Collections.addAll(argsForZygote, extraArgs);}synchronized(mLock) {// The USAP pool can not be used if the application will not use the systems graphics// driver.  If that driver is requested use the Zygote application start path.return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),useUsapPool,argsForZygote);}}

通过socket向zygote进程发送请求fork子进程,后续就是zygote fork子进程的流程了。
看到这里很多人可能有疑问,就是Activity是如何运行在fork的子进程的呢?这里就需要ActivityThread这个纽带了,zygote进程fork子进程后,会调用ActivityThread的main方法。在main方法中创建了ActivityThread对象并调用attach方法。在attach方法中:

    RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManager.getService();try {mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}

跨进程调用SystemServer进程中的ActivityManagerService.attachApplication方法 --> attachApplicationLocked()

// See if the top visible activity is waiting to run in this process...
if (normalMode) {try {didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}
}

上面代码调用ActivityTaskManagerService的attachApplication方法 -> RootActivityContainer.attachApplication()

boolean attachApplication(WindowProcessController app) throws RemoteException {final String processName = app.mName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {final ActivityDisplay display = mActivityDisplays.get(displayNdx);final ActivityStack stack = display.getFocusedStack();if (stack != null) {stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);final ActivityRecord top = stack.topRunningActivityLocked();final int size = mTmpActivityList.size();for (int i = 0; i < size; i++) {final ActivityRecord activity = mTmpActivityList.get(i);if (activity.app == null && app.mUid == activity.info.applicationInfo.uid&& processName.equals(activity.processName)) {try {if (mStackSupervisor.realStartActivityLocked(activity, app,top == activity /* andResume */, true /* checkConfig */)) {didSomething = true;}} catch (RemoteException e) {Slog.w(TAG, "Exception in new application when starting activity "+ top.intent.getComponent().flattenToShortString(), e);throw e;}}}}}if (!didSomething) {ensureActivitiesVisible(null, 0, false /* preserve_windows */);}return didSomething;
}

在此方法中调用了mStackSupervisor.realStartActivityLocked(),在前面讲ActivityStackSupervisor.startSpecificActivityLocked()调用的时候由于application并没有运行,所以要先进行进程的创建并启动,而不执行realStartActivityLocked。

调用realStartActivityLocked方法,接下来就是启动Activity的流程。
在realStartActivityLocked方法中,创建了ClientTranscation对象,并调用ActivityTaskManagerService的ScheduleTranscation方法。

     // Create activity launch transaction.final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);final DisplayContent dc = r.getDisplay().mDisplayContent;//添加回调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));// Set desired final state.final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());} else {lifecycleItem = PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// Schedule transaction.mService.getLifecycleManager().scheduleTransaction(clientTransaction);

ActivityTaskManagerService的scheduleTranscation方法中给ClientTranscation添加了callback并调用了clientTranscation的schedule方法,并调用ApplicationThread的scheduleTransaction方法 ->ActivityThread.scheduleTransaction方法,在ActivityThread中并没有找到scheduleTransaction方法因此去其父类ClientTranscationHandler查找。

void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

此处通过Handler发送消息到ActivityThread中处理,在handleMessage中找到EXECUTE_TRANSACTION消息,然后执行TransactionExecutor.execute方法

    public void execute(ClientTransaction transaction) {if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");final IBinder token = transaction.getActivityToken();if (token != null) {final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =mTransactionHandler.getActivitiesToBeDestroyed();final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);if (destroyItem != null) {if (transaction.getLifecycleStateRequest() == destroyItem) {// It is going to execute the transaction that will destroy activity with the// token, so the corresponding to-be-destroyed record can be removed.activitiesToBeDestroyed.remove(token);}if (mTransactionHandler.getActivityClient(token) == null) {// The activity has not been created but has been requested to destroy, so all// transactions for the token are just like being cancelled.Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"+ transactionToString(transaction, mTransactionHandler));return;}}}if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));executeCallbacks(transaction);executeLifecycleState(transaction);mPendingActions.clear();if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");}

执行executeCallbacks

    public void executeCallbacks(ClientTransaction transaction) {final List<ClientTransactionItem> callbacks = transaction.getCallbacks();if (callbacks == null || callbacks.isEmpty()) {// No callbacks to execute, return early.return;}if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");final IBinder token = transaction.getActivityToken();ActivityClientRecord r = mTransactionHandler.getActivityClient(token);// In case when post-execution state of the last callback matches the final state requested// for the activity in this transaction, we won't do the last transition here and do it when// moving to final state instead (because it may contain additional parameters from server).final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState(): UNDEFINED;// Index of the last callback that requests some post-execution state.final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);final int size = callbacks.size();for (int i = 0; i < size; ++i) {final ClientTransactionItem item = callbacks.get(i);if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);final int postExecutionState = item.getPostExecutionState();final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,item.getPostExecutionState());if (closestPreExecutionState != UNDEFINED) {cycleToPath(r, closestPreExecutionState, transaction);}item.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);if (r == null) {// Launch activity request will create an activity record.r = mTransactionHandler.getActivityClient(token);}if (postExecutionState != UNDEFINED && r != null) {// Skip the very last transition and perform it by explicit state request instead.final boolean shouldExcludeLastTransition =i == lastCallbackRequestingState && finalState == postExecutionState;cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);}}}

这里的callbacks就是在realStartActivityLocked方法中添加的,为LaunchActivityItem。因此最终执行的是LaunchActivityItem的execute方法。

@Override
public void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,mPendingResults, mPendingNewIntents, mIsForward,mProfilerInfo, client, mAssistToken);client.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

执行client.handleLaunchActivity(),client为ClientTransactionHandler,通过execute传参,在构造TransactionExecutor对象时传入,即ActivityThread,因此最后又回到ActivityThread.handleLaunchActivity方法

Launcher进程启动流程相关推荐

  1. Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]

    摘要:上一节我们讲完了Android10.0的ActivityManagerService的启动流程,在AMS的最后启动了Launcher进程,今天我们就来看看Launcher的真正启动流程. 阅读本 ...

  2. Zygote进程启动流程分析

    文中的源代码版本为api23 Zygote进程启动流程分析 先说结论,zygote进程启动过程中主要做了下面这些事情: 启动DVM虚拟机 预加载部分资源,如一些通用类.通用资源.共享库等 启动syst ...

  3. 【Android】系统启动流程(zygote 进程启动流程)

    前言 先上图,大致了解一下 Android 设备点击电源键开机到创建出 system_server 进程的流程, 里面细化的子流程和 system_server 之后发生的事情我将会在后续的文章中详细 ...

  4. Android应用程序进程启动流程

    在学习应用程序进程启动流程前,先要弄清楚系统启动流程,如果有不清楚的同学,建议先看下以前博主的文章: Android系统启动(上篇)_AD钙奶-lalala的博客-CSDN博客 Android系统启动 ...

  5. Android系统启动流程(四)Launcher进程启动过程解析(附带面试题)

    前面我们分析了init进程,zygote进程,SystemServer进程,本篇的Launcher是系统启动流程的最后一个进程. 1 Launcher概述 Launcher进程是一个系统的应用程序,位 ...

  6. Android系统启动流程—— init进程zygote进程SystemServer进程启动流程

    原文地址:https://blog.csdn.net/qq_30993595/article/details/82714409 Android系统启动流程 Android系统启动过程往细了说可以分为5 ...

  7. 从源码解析-Android系统启动流程概述 init进程zygote进程SystemServer进程启动流程

    Android系统启动流程 启动流程 Loader Kernel Native Framework Application init进程 启动 rc文件规则 Actions Commands Serv ...

  8. Android系统的心脏-Zygote进程启动流程分析

    简介: Android中,Zygote是整个Android系统的核心进程,是Android系统的心脏.所有的Android应用程序,包括Android框架层所在的进程system_server,都是由 ...

  9. ceph进程启动流程

    2019独角兽企业重金招聘Python工程师标准>>> 转载于:https://my.oschina.net/u/2874260/blog/1592612

最新文章

  1. [转] fastText
  2. AlphaImageLoader用法
  3. 高级交叉报表例子程序(C#)中明细列统计数据错误改正!
  4. RxSwift之UI控件UISlider与UIStepper扩展的使用
  5. 《Python Cookbook 3rd》笔记(4.13):创建数据处理管道
  6. TensorFlow学习笔记02:TensorBoard可视化入门
  7. python和java的区别-一张图秒懂Java和Python的区别,你知道吗?
  8. bzoj2756: [SCOI2012]奇怪的游戏
  9. 隐马尔可夫模型HMM[转载牛人,看了半天没看懂]
  10. Git客户端Tower for Mac 8.2
  11. JAVA300集速学堂高淇个人笔记P1-P7如何学习JAVA300集计算机语言的发展历史多种编程语言的介绍JAVA三大版本的含义:
  12. 桑格测序服务市场现状及未来发展趋势
  13. gdb学习20:总结
  14. 小米note 卡在android,小米note怎么插卡?小米note详细插卡教程分享
  15. KB927917解决方法
  16. MC模组发布:Joy的枪械工坊
  17. 慕容不复_拔剑-浆糊的传说_新浪博客
  18. 奥运上最幸福的失意人-劳伦杰克逊
  19. python爬虫登录微博_python爬虫-模拟微博登录功能
  20. AMQ的一些简单实战

热门文章

  1. Android 微信抢红包插件
  2. 维修服务器bga是什么,服务器主板芯片坏了有机器能拆除焊接BGA吗?
  3. maven 树 查看依赖
  4. Abelssoft SSD Fresh Plus 2021 v10.06.31890 固态硬盘性能优化工具中文版
  5. C++ 学习——char * ,char a[ ],char ** ,char *a[] 的区别
  6. ffmpeg 音频解码二
  7. 如何查找IBM P5、6的HMC管理地址
  8. EOS的经济模型是什么?
  9. Cool Edit Pro 常用快捷键
  10. ai不同形状的拼版插件_Illustrator自动拼版脚本插件-AI自动拼版脚本下载-西西软件下载...