startActivity桌面启动应用

android12-release


1. Launcher点击应用图标

packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.java
packages/apps/Launcher3/src/com/android/launcher3/BaseActivity.java

onClickAppShortcut -> startAppShortcutOrInfoActivity -> launcher.startActivitySafely -> startActivity()最后调用到Activity.java中。

其中intent包含信息:
action = “android.intent.action.MAIN”
category=“android.intent.category.LAUNCHER”
cmp=“[包名]/.MainActivity”

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 配合android:taskAffinity,默认为包名,冷启动应用时Activity在新的任务栈中启动

<activity android:name=".MainActivity"  android:label="@string/app_name">  <intent-filter>  <action android:name="android.intent.action.MAIN" />  <category android:name="android.intent.category.LAUNCHER" />  </intent-filter>
</activity>

2. 桌面Activity – Instrumentation – AMS/ATMS

  • mParent 应用首次启动所以mParent为空。
  • mMainThread.getApplicationThread() 获取ApplicationThread成员变量,是一个Binder对象
  • mToken Activity类的成员变量,它是一个Binder对象的远程接口
  • ActivityTaskManager.getService() 获取Context.ACTIVITY_TASK_SERVICE 即是 ActivityTaskManagerService
  • Instrumentation.java 用来监控应用程序和系统的交互
  • checkStartActivityResult(result, intent); 检查是否启动成功

startActivity() -> startActivityForResult -> mInstrumentation.execStartActivity -> ActivityTaskManager.getService().startActivity

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

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {if (mParent == null) {options = transferSpringboardActivityOptions(options);Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);// ... ...} else {// ... ...}}
    public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {// ... ...try {intent.migrateExtraStreamToClipData(who);intent.prepareToLeaveProcess(who);int result = ActivityTaskManager.getService().startActivity(whoThread,who.getOpPackageName(), who.getAttributionTag(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()), token,target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;}

2.1 ActivityTaskManager.getService()

  • IActivityTaskManagerSingleton.get()单例模式,Android 中 java 单例模板frameworks/base/core/java/android/util/Singleton.java,查看单例模式(Singleton) 2
  • 使用Binder IPC获取查看Binder系列3-framework层
  • Context.ACTIVITY_TASK_SERVICE AMS服务启动时注册到binder,ActivityManagerService启动-android12

3. Binder IPC调用到 ActivityTaskManagerService

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

ActivityTaskManager.getService().startActivity -> startActivityAsUser() -> getActivityStartController().obtainStarter ........ execute() -> executeRequest(mRequest) -> startActivityUnchecked() -> startActivityInner()

  • obtainStarter(intent, "startActivityAsUser")工厂模式mFactory.obtain().setIntent(intent).setReason(reason)获取ActivityStarter
  • executeRequest(mRequest)这里输出START u日志,一般定制都会加上pid打印
  • ActivityRecord r,sourceRecord信息
  • startActivityInner()该方法有许多参数处理,如setInitialState\computeLaunchingTaskFlags\computeSourceStack\mIntent.setFlags(mLaunchFlags)\computeLaunchParams
  • startActivityInner() 这里wm_create_taskwm_create_activity
if (newTask) {EventLogTags.writeWmCreateTask(mStartActivity.mUserId,mStartActivity.getTask().mTaskId);}mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, mStartActivity.getTask());
  • mDoResume移到栈顶显示resumeFocusedTasksTopActivities

3.1 先startPausingLocked

mRootWindowContainer.resumeFocusedTasksTopActivities -> resumeTopActivityUncheckedLocked -> resumeTopActivityInnerLocked -> 先startPausingLocked后mTaskSupervisor.startSpecificActivity(next, true, true)

next.attachedToProcess()此时由于第一次(冷启动)为false,主要在Task.java操作resumeTopActivityInnerLocked()

  • 此时当前mResumedActivity != null,即为桌面Launcher,先startPausingLocked() 执行Pausing过程,并输出日志wm_pause_activity
if (mResumedActivity != null) {ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity);pausing |= startPausingLocked(false /* uiSleeping */, next,"resumeTopActivityInnerLocked");
}
  • prev = mResumedActivity、mPausingActivity = prev赋值mPausingActivity,并设置状态prev.setState(PAUSING, "startPausingLocked")

  • EventLogTags.writeWmPauseActivity() Event日志

  • mAtmService.getLifecycleManager().scheduleTransaction()执行PauseActivityItem,通过ActivityThread、Instrumentation.callActivityOnPause()通知到Activity onPause(),并输出wm_on_paused_calledAndroid P Basic lifecycle transaction containers --设计模式体现之策略模式

  • completePauseLocked(false, resuming) pause完成,并设置状态prev.setState(PAUSED, "completePausedLocked");

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

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,ActivityRecord resuming, String reason) {// ... ...ActivityRecord prev = mResumedActivity;// ... ...ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev);mPausingActivity = prev;mLastPausedActivity = prev;if (prev.isNoHistory() && !mTaskSupervisor.mNoHistoryActivities.contains(prev)) {mTaskSupervisor.mNoHistoryActivities.add(prev);}prev.setState(PAUSING, "startPausingLocked");prev.getTask().touchActiveTime();// ... ...boolean didAutoPip = false;if (prev.attachedToProcess()) {if (shouldAutoPip) {// ... ...} else {ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);try {EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),prev.shortComponentName, "userLeaving=" + userLeaving, reason);mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,prev.configChangeFlags, pauseImmediately));} catch (Exception e) {// ... ...}}} else {// ... ...}// ... ...// ... ...if (pauseImmediately) {// If the caller said they don't want to wait for the pause, then complete// the pause now.completePauseLocked(false, resuming);return false;}// ... ...}
  • 先走这里mTaskSupervisor.startSpecificActivity,执行realStartActivityLocked();没有启动执行mService.startProcessAsync()

3.2 startSpecificActivity启动:AMS/ATMS -- Instrumentation -- 应用Activity

  • WindowProcessController wpc第一次启动获取到的是null;mService.startProcessAsync()先fork应用进程

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.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 {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.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}

3.2.1 启动ActivityThread(内部成员ApplicationThread)

  • startProcessAsync通过ATMS/AMS走到ProcessList.javastartProcess()调用Process.start,通过ZYGOTE_PROCESS.start fork生成进程,最后执行到 ActivityThread.main() 方法回调AMS.attachApplication
    public static void main(String[] args) {// ... ...Looper.prepareMainLooper();// ... ...ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);// ... ...Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}

相关查看ActivityThread应用进程

  • ProcessList.java中handleProcessStartedLocked输出am_proc_startAMS.attachApplication输出am_proc_bound
EventLog.writeEvent(EventLogTags.AM_PROC_START,UserHandle.getUserId(app.getStartUid()), pid, app.getStartUid(),app.processName, app.getHostingRecord().getType(),app.getHostingRecord().getName() != null ? app.getHostingRecord().getName() : "");EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
  • 几经attachApplication:AMS.attachApplication -> ATMS.attachApplication -> RootWindowContainer.attachApplication(wpc) -> mTaskSupervisor.realStartActivityLocked();最终还是调用到realStartActivityLocked
  • AMS.attachApplicationthread.bindApplication()创建Instrumentationapp = data.info.makeApplication(data.restrictedBackupMode, null),并通过Instrumentation通知到Application:
mInstrumentation.onCreate(data.instrumentationArgs);
mInstrumentation.callApplicationOnCreate(app);

3.2.2 realStartActivityLocked()真正启动APP

ActivityThread.main() -> AMS.attachApplication -> ATMS.attachApplication -> RootWindowContainer.attachApplication(wpc) / startActivityForAttachedApplicationIfNeeded -> mTaskSupervisor.realStartActivityLocked()

  • Event日志wm_restart_activity
EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),task.mTaskId, r.shortComponentName);
  • mService.getLifecycleManager().scheduleTransaction(clientTransaction);通知到Activity Resumed: wm_on_resume_called
mInstrumentation.callActivityOnResume(this);
EventLogTags.writeWmOnResumeCalled(mIdent, getComponentName().getClassName(), reason);
  • 与上面pause不同的是添加了LaunchActivityItem

frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
(Android P Basic lifecycle transaction containers--设计模式体现之策略模式)

  • TransactionExecutor先执行executeCallbacks即执行LaunchActivityItem,所以在Resuemed之前处理handleLaunchActivity()
  1. 初始化activity = mInstrumentation.newActivity()
  2. activity.attach() 处理WMS相关信息
  3. mInstrumentation.callActivityOnCreate()通知onCreate,设置ActivityClientRecord r.setState(ON_CREATE);
  4. executeLifecycleState(transaction)ON_CREATEON_RESUME之间添加ON_START流程: mHelper.getLifecyclePath(start, finish, excludeLastState)

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

    public void execute(ClientTransaction transaction) {// ... ...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");}

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

    public Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, Intent customIntent) {// ... ...// Make sure we are running with the most recent config.mConfigurationController.handleConfigurationChanged(null, null);if (localLOGV) Slog.v(TAG, "Handling launch of " + r);// Initialize before creating the activityif (ThreadedRenderer.sRendererEnabled&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {HardwareRenderer.preload();}WindowManagerGlobal.initialize();// Hint the GraphicsEnvironment that an activity is launching on the process.GraphicsEnvironment.hintActivityLaunch();final Activity a = performLaunchActivity(r, customIntent);// ... ...}

4. 时序图

待续~~~ 道阻且长


Log关键字:
ActivityTaskManager: START u|ActivityTaskManager: Displayed
wm_create_activity|wm_set_resumed_activity|wm_resume_activity|wm_on_resume_called|wm_activity_launch_time


06-13 23:14:02.056 1000 1787 10268 I wm_create_task: [0,109]
06-13 23:14:02.056 1000 1787 10268 I wm_create_activity: [0,103558740,109,com.tencent.mobileqq/.activity.SplashActivity,android.intent.action.MAIN,NULL,NULL,270532608]
06-13 23:14:02.059 1000 1787 10268 I wm_pause_activity: [0,3858326,com.miui.home/.launcher.Launcher,userLeaving=true]
06-13 23:14:02.067 10083 22061 22061 I wm_on_paused_called: [0,com.miui.home.launcher.Launcher,performPause,1]

06-13 23:14:02.114 1000 1787 3359 I wm_restart_activity: [0,103558740,109,com.tencent.mobileqq/.activity.SplashActivity]
06-13 23:14:02.117 1000 1787 3359 I wm_set_resumed_activity: [0,com.tencent.mobileqq/.activity.SplashActivity,minimalResumeActivityLocked]
06-13 23:14:02.876 10264 26092 26092 I wm_on_create_called: [0,com.tencent.mobileqq.activity.SplashActivity,performCreate,105]
06-13 23:14:02.878 10264 26092 26092 I wm_on_start_called: [0,com.tencent.mobileqq.activity.SplashActivity,handleStartActivity,1]
06-13 23:14:02.885 10264 26092 26092 I wm_on_resume_called: [0,com.tencent.mobileqq.activity.SplashActivity,RESUME_ACTIVITY,7]
06-13 23:14:02.899 10264 26092 26092 I wm_on_top_resumed_gained_called: [103558740,com.tencent.mobileqq.activity.SplashActivity,topStateChangedWhenResumed]
06-13 23:14:02.988 1000 1787 1839 I wm_activity_launch_time: [0,103558740,com.tencent.mobileqq/.activity.SplashActivity,954]


相关文章:

Android应用程序启动过程源代码分析
Android应用程序内部启动Activity过程(startActivity)的源代码分析
startActivity启动过程分析
【 Android 10 四大组件 】系列 – Activity 的“启动流程”
Android之Activity启动流程详解(基于api28)

AMS:startActivity桌面启动应用相关推荐

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

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

  2. Android-0.AMS初始化和启动简介

    文章目录 1.Activity Manager简介 2.AMS 的启动和初始化过程 2.1.AMS 所在的system进程 2.1.AMS 初始化流程 2.2.AMS 启动流程 2.3.AMS 的 s ...

  3. 安卓startActivity:彻底理解startActivity的启动过程这一篇就够了

    基于Android 6.0的源码剖析, 分析android Activity启动流程,相关源码: frameworks/base/services/core/java/com/android/serv ...

  4. Launch 桌面启动详解

    Launch 桌面启动详解 不管是开机还是重启手机,相信我们大家都不陌生吧.大部分的 90 后都经历了从 Android 2.* 的统一开机动画,到现在 Android 10 的各种定制开机动画. 为 ...

  5. 【解决方案】Ubuntu设置Matlab桌面启动快捷方式

    [解决方案]Ubuntu设置Matlab桌面启动快捷方式 Ubuntu系统包括两个快捷方式的路径: 坞站(dock)--所有用户可见 桌面快捷键--当前用户可见 坞站(dock)快捷方式的路径/usr ...

  6. 超融合如何克服启动风暴?云桌面启动风暴的解决办法

    或许在办公时,你也遇到过这些问题:办公室突然断电来不及保存数据,导致数据丢失:休息时被迫听着电脑嗡嗡作响的声音:运维人员不得不时常打补丁.装软件.修电脑和重装系统等等.然而,云桌面的出现改变了企业传统 ...

  7. Ubuntu桌面启动后自动执行指定的命令或程序的三种方法

     使用Ubuntu的过程中,经常会开机后执行一些固定的动作,每次手工操作很麻烦.其实Ubuntu有很多方法可以自动执行脚本和命令,先来介绍三种最简单的,文章最后会提到几种其他的方法. 一.基于图形桌面 ...

  8. Linux如何让一个.sh文件可双击执行 并设置桌面启动图标

    Linux如何让一个.sh文件可双击执行并设置桌面启动图标 linux下怎么设置一个.sh文件可执行 参考资料: https://blog.csdn.net/ahelloyou/article/det ...

  9. 虚拟桌面启动后自动全屏

    如果客户端有多个显示器,打开虚拟桌面后,如果需要进入到全屏模式(覆盖所有的客户端显示器),目前还是需要一定技巧的,需要把桌面拖放到两个屏幕的中间,然后全屏才可以实现.否则,简单的全屏只会覆盖当前所在的 ...

  10. CentOS 桌面启动无登录界面

    最近VMWare下搞了2个CentOS 32bit虚拟机, 装了些软件之后,都遇到开机无法显示登录界面, 仅能看见桌面背景图的情况.  以下是我搜索很久汇总的方法. 尝试按 ctrl + alt + ...

最新文章

  1. 简明python教程 --C++程序员的视角(九):函数式编程、特殊类方法、测试及其他...
  2. HashMap实现相同key,对value的操作
  3. raspbian wifi设置
  4. 洛谷P7361:拜神(SA、二分、主席树、启发式合并)
  5. Loj#6039-「雅礼集训 2017 Day5」珠宝【四边形不等式,dp】
  6. mysql堆溢出_为什么这个MySQL触发器会导致堆栈溢出?
  7. 基于JAVA+SpringMVC+Mybatis+MYSQL的毕业论文设计管理系统
  8. Java基础学习总结(42)——Log4j 2快速入门及Log4j 2 + Slf4j 的配置和使用
  9. JAVA零碎要点015---java BigDecimal常见操作_加减乘除操作_比较_取几位小数四舍五入_随时更新
  10. [转]Django REST framework 简介与中文教程
  11. 迁移用友U8 ERP服务器
  12. 学习python内一般函数知识
  13. mysql中为啥只显示一条语句_MySQL 笔记整理(19) --为什么我只查一行的语句,也执行这么慢?...
  14. 原生JS和NodeJS之间的区别
  15. macOS Big Sur 11.5 (20G71) 虚拟机 ISO 镜像
  16. 收藏到一个好的java时间格式大全(类)
  17. python二手房使用教程_python爬取安居客二手房网站数据方法分享
  18. img图片在父元素中居中的方法
  19. JavaScript getDay()与getDate()
  20. 微信小程序初探【类微信UI聊天简单实现】

热门文章

  1. 光时域反射仪 光通信工程TFN F7 OTDR 测试耗损必备
  2. otool 分析Mach-O
  3. CAN网络错误帧排查
  4. Navicat15注册时报错 rsa public key not find
  5. 初学python100例-案例23 python输出菱形图案 青少年python编程 少儿编程案例讲解
  6. scratch动态三角形拖动/自制素材/少儿编程scratch教研教案课件课程素材脚本
  7. PCB,原理图 最流行的画图画板软件有哪些?
  8. 20180329整理巡检系统代码
  9. 从金蝶k3到金税盘_金蝶k3怎样结转主营业务成本
  10. 小米笔记本linux指纹,小米笔记本Air13.3寸指纹版(128GB) u盘装系统win10步骤