AMS:startActivity桌面启动应用
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
即是 ActivityTaskManagerServiceInstrumentation.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)
获取ActivityStarterexecuteRequest(mRequest)
这里输出START u
日志,一般定制都会加上pid
打印
ActivityRecord r,sourceRecord
信息startActivityInner()
该方法有许多参数处理,如setInitialState
\computeLaunchingTaskFlags
\computeSourceStack
\mIntent.setFlags(mLaunchFlags)
\computeLaunchParams
startActivityInner()
这里wm_create_task
、wm_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()
通知到ActivityonPause()
,并输出wm_on_paused_called
(Android 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.java
中startProcess()
调用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_start
、AMS.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.attachApplication
中thread.bindApplication()
创建Instrumentation
、app = 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()
:
- 初始化
activity = mInstrumentation.newActivity()
activity.attach()
处理WMS相关信息mInstrumentation.callActivityOnCreate()
通知onCreate,设置ActivityClientRecord r.setState(ON_CREATE);
executeLifecycleState(transaction)
在ON_CREATE
和ON_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桌面启动应用相关推荐
- Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]
摘要:上一节我们讲完了Android10.0的ActivityManagerService的启动流程,在AMS的最后启动了Launcher进程,今天我们就来看看Launcher的真正启动流程. 阅读本 ...
- Android-0.AMS初始化和启动简介
文章目录 1.Activity Manager简介 2.AMS 的启动和初始化过程 2.1.AMS 所在的system进程 2.1.AMS 初始化流程 2.2.AMS 启动流程 2.3.AMS 的 s ...
- 安卓startActivity:彻底理解startActivity的启动过程这一篇就够了
基于Android 6.0的源码剖析, 分析android Activity启动流程,相关源码: frameworks/base/services/core/java/com/android/serv ...
- Launch 桌面启动详解
Launch 桌面启动详解 不管是开机还是重启手机,相信我们大家都不陌生吧.大部分的 90 后都经历了从 Android 2.* 的统一开机动画,到现在 Android 10 的各种定制开机动画. 为 ...
- 【解决方案】Ubuntu设置Matlab桌面启动快捷方式
[解决方案]Ubuntu设置Matlab桌面启动快捷方式 Ubuntu系统包括两个快捷方式的路径: 坞站(dock)--所有用户可见 桌面快捷键--当前用户可见 坞站(dock)快捷方式的路径/usr ...
- 超融合如何克服启动风暴?云桌面启动风暴的解决办法
或许在办公时,你也遇到过这些问题:办公室突然断电来不及保存数据,导致数据丢失:休息时被迫听着电脑嗡嗡作响的声音:运维人员不得不时常打补丁.装软件.修电脑和重装系统等等.然而,云桌面的出现改变了企业传统 ...
- Ubuntu桌面启动后自动执行指定的命令或程序的三种方法
使用Ubuntu的过程中,经常会开机后执行一些固定的动作,每次手工操作很麻烦.其实Ubuntu有很多方法可以自动执行脚本和命令,先来介绍三种最简单的,文章最后会提到几种其他的方法. 一.基于图形桌面 ...
- Linux如何让一个.sh文件可双击执行 并设置桌面启动图标
Linux如何让一个.sh文件可双击执行并设置桌面启动图标 linux下怎么设置一个.sh文件可执行 参考资料: https://blog.csdn.net/ahelloyou/article/det ...
- 虚拟桌面启动后自动全屏
如果客户端有多个显示器,打开虚拟桌面后,如果需要进入到全屏模式(覆盖所有的客户端显示器),目前还是需要一定技巧的,需要把桌面拖放到两个屏幕的中间,然后全屏才可以实现.否则,简单的全屏只会覆盖当前所在的 ...
- CentOS 桌面启动无登录界面
最近VMWare下搞了2个CentOS 32bit虚拟机, 装了些软件之后,都遇到开机无法显示登录界面, 仅能看见桌面背景图的情况. 以下是我搜索很久汇总的方法. 尝试按 ctrl + alt + ...
最新文章
- 简明python教程 --C++程序员的视角(九):函数式编程、特殊类方法、测试及其他...
- HashMap实现相同key,对value的操作
- raspbian wifi设置
- 洛谷P7361:拜神(SA、二分、主席树、启发式合并)
- Loj#6039-「雅礼集训 2017 Day5」珠宝【四边形不等式,dp】
- mysql堆溢出_为什么这个MySQL触发器会导致堆栈溢出?
- 基于JAVA+SpringMVC+Mybatis+MYSQL的毕业论文设计管理系统
- Java基础学习总结(42)——Log4j 2快速入门及Log4j 2 + Slf4j 的配置和使用
- JAVA零碎要点015---java BigDecimal常见操作_加减乘除操作_比较_取几位小数四舍五入_随时更新
- [转]Django REST framework 简介与中文教程
- 迁移用友U8 ERP服务器
- 学习python内一般函数知识
- mysql中为啥只显示一条语句_MySQL 笔记整理(19) --为什么我只查一行的语句,也执行这么慢?...
- 原生JS和NodeJS之间的区别
- macOS Big Sur 11.5 (20G71) 虚拟机 ISO 镜像
- 收藏到一个好的java时间格式大全(类)
- python二手房使用教程_python爬取安居客二手房网站数据方法分享
- img图片在父元素中居中的方法
- JavaScript getDay()与getDate()
- 微信小程序初探【类微信UI聊天简单实现】
热门文章
- 光时域反射仪 光通信工程TFN F7 OTDR 测试耗损必备
- otool 分析Mach-O
- CAN网络错误帧排查
- Navicat15注册时报错 rsa public key not find
- 初学python100例-案例23 python输出菱形图案 青少年python编程 少儿编程案例讲解
- scratch动态三角形拖动/自制素材/少儿编程scratch教研教案课件课程素材脚本
- PCB,原理图 最流行的画图画板软件有哪些?
- 20180329整理巡检系统代码
- 从金蝶k3到金税盘_金蝶k3怎样结转主营业务成本
- 小米笔记本linux指纹,小米笔记本Air13.3寸指纹版(128GB) u盘装系统win10步骤