Launcher 启动 activity 流程
基于 android9.0
文章记录一个大概的流程,方便以后参考
启动流程简述
- Launcher 里的icon点击,执行到AMS.startActivity(),告诉 AMS 我要启动一个新的 activity
- Launcher 进程 标记 A , AMS 进程标记 B
- Launcher APP 执行 onPause
- AMS从ProcessRecord中发现当前 APP 进程未启动,创建 APP进程标记 C,然后启动ActivityThread
- APP进程 C 初始化
- 启动APP 进程的 Activity
begin
【packages/apps/Launcher3/src/com/android/launcher3】
我们在桌面点击 APP 的icon点击事件就是在这儿的onClick()里发起的
public class ItemClickHandler {
private static void onClick(View v) {
//...
// Start activities
startAppShortcutOrInfoActivity(v, shortcut, launcher);
}
}
方法的调用链:
【Launcher.java】
Launcher. startActivitySafely()//内部调用父类的startActivitySafely()方法
【--->BaseDraggingActivity.java】
BaseDraggingActivity.startActivitySafely()//调用Activity 的startActivity()方法
【--->Activity.java】
进入Activity
Activity.startActivity()
//...
Activity.startActivityForResult()//调用Instrumentation.execStartActivity()方法
【--->Instrumentation.java】
至此,我们在 launcher 进程的桌面中点击 icon, 执行到Instrumentation.execStartActivity()方法
public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
//...
try {
//这儿
//whoThread :launcher 进程中ActivityThread的ApplicationThread 对象,它是一个IApplicationThread类型的
//intent : 跳转的信息
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
} catch (RemoteException e) {
}
return null;
}
}
告诉 AMS 我要启动一个新的 activity
ActivityManager.getService()获取到 AMS 的代理对象,执行startActivity()
接着就进入到 AMS 的 startActivity() 方法
【--->ActivityManagerService.java】
ActivityManagerService.startActivity()
//...
ActivityManagerService.startActivityAsUser()//execute()
【--->ActivityStarter.java】
ActivityStarter.execute()
//
ActivityStarter.startActivityMayWait()
//
ActivityStarter.startActivity()
//
ActivityStarter.startActivityUnchecked()//调用resumeFocusedStackTopActivityLocked()
//
【--->ActivityStackSupervisor.java】
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
//调用ActivityStack.resumeTopActivityUncheckedLocked()
告诉 ASM Launcher APP 执行 onPause
【--->ActivityStack.java】
ActivityStack.resumeTopActivityUncheckedLocked()
//
ActivityStack.resumeTopActivityInnerLocked()//方法内部两个流程
//流程1. pause 当前的 activity
ActivityStack.startPausingLocked
//流程2.创建进程
//调用 ActivityStackSupervisor.startSpecificActivityLocked()
APP 进程未创建,创建进程 并初始化
再次回到ActivityStackSupervisor
【--->ActivityStackSupervisor.java】
public class ActivityStackSupervisor {
//...
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//从AMS中查询将要启动的Activity的进程是否存在
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
getLaunchTimeTracker().setLaunchTime(r);
//如果应用进程已经存在
if (app != null && app.thread != null) {
try {
//...
//如果是 APP 内启动新 Activity 则执行这个分支
realStartActivityLocked(r, app, andResume, checkConfig);
//return 下面的不会执行了
return;
} catch (RemoteException e) {
}
}
//launcher 启动 APP 执行这个逻辑
//进程不存在,通过AMS调用startProcessLocked向Zygote进程发送请求
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
}
应用进程的创建过程,这里不说,APP进程创建之后 入口是 ActivityThread 的 Main()
此时 APP 进程起来了 ,我们的逻辑在 APP进程内,目前涉及到的进程
Launcher进程 :A
AMS 进程 :B
APP 进程 :C
然后APP进程 C 初始化
- 初始化Application ,即回调APP进程里的Application的 OnCreate()方法,这一步暂不分析
- 启动 Activity
public final class ActivityThread extends ClientTransactionHandler {
public static void main(String[] args) {
//...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
//ActivityThread的attach()
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//...
Looper.loop();
}
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
//...
if (!system) {
final IActivityManager mgr = ActivityManager.getService();
try {
//AMS绑定ApplicationThread对象
//APP 进程和AMS进程开始通信通信
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
}
} else {
}
//...
}
}
启动APP 进程的 Activity
【--->AMS.java】
ActivityManagerService.attachApplication()
//
ActivityManagerService.attachApplicationLocked()
//1. thread.bindApplication
//2.mStackSupervisor.attachApplicationLocked(app) 分析这一步
再次回到ActivityStackSupervisor
【--->ActivityStackSupervisor.java】
public class ActivityStackSupervisor {
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
if (activity.app == null && app.uid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
//还是到这儿
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
}
}
}
}
return didSomething;
}
}
【--->ActivityThread.java】
ActivityThread.handleLaunchActivity()
//
ActivityThread.performLaunchActivity()//通过反射创建 activity
// 依次回调 activity 的
Activity.attach()
Activity.onCreate()
Activity.start()
Activity.onResume()
其他
- 进程内 activity 启动
- setContentView 过程
见相关文章
更多内容 欢迎关注公众号
- hdu---------(1026)Ignatius and the Princess I(bfs+dfs)
- hdu-----(1113)Word Amalgamation(字符串排序)
- HDUoj-------(1128)Self Numbers
- cf------(round 2)A. Winner
- cf------(round)#1 C. Ancient Berland Circus(几何)
- MySQL配置TokuDB的简单总结
- cf------(round)#1 B. Spreadsheets(模拟)
- sysbench压测MyCAT的shell脚本
- qemu-kvm中vcpu虚拟化到底是咋整的?
- 【给 iOS 开发者】人工智能在 iOS 开发上的应用和机会
- 【Python】Selenium辅助海量基金数据获取
- Django ORM的简单总结
- GO语言标准库概览
- 关于自动化平台的动态菜单设计
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 使用‘fsck’修复Linux中文件系统错误的方法
- linux/OSX中“DD”命令制作ISO镜像操作系统安装U盘的方法
- 《高效能程序员的修炼》读书笔记
- linux之centos7防火墙基本使用详解
- Ubuntu安装scrcpy完成手机投屏和控制(Ubuntu用QQ微信的另一种方法)
- CentOS7 systemd添加自定义系统服务的方法
- Linux中sudo、su和su -命令的区别小结
- 非零环绕规则
- Linux被中断的系统如何调用详解
- centos 修改ssh默认端口号的方法示例
- Linux中特殊权限SUID、SGID与SBIT的深入讲解
- linux新文件权限设置之umask的深入理解
- 在 CentOS 8/RHEL 8 上安装和使用 Cockpit的方法
- Linux删除文件提示Operation not permitted的处理办法
- 微任务与宏任务