zygoteinit.java_源码跟踪之启动流程:从ZygoteInit到onCreate

Instrumentation

SDK版本名称: Pie

API Level: 28

一、源码调用时序图

1. Activity的启动流程

说明:其中ActivityThread中执行的scheduleTransaction方法在其父类ClientTransactionHandler中,发送了ActivityThread.H.EXECUTE_TRANSACTION,ActivityThread接收后执行了LaunchActivityItem#execute()

785cdb5736d1

Activity的启动流程.jpg

2.ActivityManagerService的启动流程

说明:其中RunnableInit通过类名反射了main方法,封装成Runnable返回,最终在ZygoteInit#main中执行run()。

785cdb5736d1

ActivityManagerService的启动流程.jpg

3.ActivityThread的启动流程

说明:图中省略了ZygoteConnection获取MethodAndArgsCaller的步骤,其步骤可参加ActivityManagerService的启动流程,也是经过WrapperInit拿到的。

785cdb5736d1

ActivityThread的启动流程 .jpg

二、流程总结

ZygoteInit#main方法中启动一个SystemServer和一个ZygoteServer。

SystemServer中通过SystemServiceManager执行onStart()的方式启动了ActivityManagerService,使用ServiceManager对其进行持久化管理。

ZygoteServer中启动了一个名为“zygote”的LocalSocket类型的socket服务。使用死循环去处理socket链接。

应用没有启动时,从Launcher进入应用,Activity中的startActivity()方法最终调用了ActivityManagerService#startProcessLocked。

这个方法中将ActivityThread的类名参数通过socket链接到ZygoteInit中启动的ZygoteServer。

ZygoteServer死循环中得到参数后,通过ZygoteConnection#processOneCommand返回一个MethodAndArgsCaller类型的Runnable,在ZygoteInit#main中执行。

(26版本会在ZygoteInit#main方法中捕获MethodAndArgsCaller类型的异常,然后捕获执行。两种写法的目的都是为了清除方法调用的堆栈信息)

ActivityThread#main方法中调用其attach方法,将创建好的ApplicationThread传给ActivityManagerService#,AMS保留参数给ProcessRecord后续使用。

应用已经启动时,Activity中的startActivity()方法调用了ActivityManagerService#startActivityAsUser,执行ActivityStarter#execute

这个方法最终调用ActivityStackSupervisor#realStartActivityLocked,以ActivityThread.mAppThread为参数创建LaunchActivityItem。然后执行AcitivityThread#scheduleTransaction方法,发送ActivityThread.H.EXECUTE_TRANSACTION。

ActivityThread接收到消息后执行LaunchActivityItem#execute,调用ActivityThread#handleLaunchActivity,最终调用ActivityThread#performLaunchActivity。

performLaunchActivity()方法通过Instrumentation#newActivity得到要启动的Activity,然后调用其attach()方法。

而后,会调用Instrumentation#callActivityOnCreate,最终调用到Activity#onCreate

三、相关文章:

四、流程记录

代码跟踪记录,只保留了关键代码,其余代码用...替代。

java类名可点击,将跳转到Android社区的sdk源代码文件。

跟踪记录的意义在于,在需要研究流程中某个环节细节问题时,可以快速定位。

private Instrumentation mInstrumentation;

public void startActivity(...) {

...

startActivityForResult(...);

...

}

public void startActivityForResult(...) {

...

mInstrumentation.execStartActivity(...);

...

}

final void performCreate(...) {

...

onCreate(...);

...

}

public ActivityResult execStartActivity(...) {

...

int result = ActivityManager.getService().startActivity(...)

...

}

public void callActivityOnCreate(...) {

...

activity.performCreate(...);

...

}

private static final Singleton IActivityManagerSingleton = () -> {

final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);

...

return am;

};

public static IActivityManager getService() {

return IActivityManagerSingleton.get();

}

public static IBinder getService(String name) {

...

IBinder service = sCache.get(name);

...

}

public static void initServiceCache(Map cache) {

...

sCache.putAll(cache);

}

ActivityStartController(ActivityManagerService service) {

this(...,new DefaultFactory(..)));

}

@VisibleForTesting

ActivityStartController(...,Factory factory) {

...

mFactory = factory;

...

}

ActivityStarter obtainStarter(...) {

return mFactory.obtain().setIntent(intent).setReason(reason);

}

private ActivityStack mTargetStack;

static class DefaultFactory implements Factory {

...

public ActivityStarter obtain() {

...

return starter;

}

...

}

int execute() {

...

if (mRequest.mayWait) {

return startActivityMayWait(...);

} else {

return startActivity(...);

}

...

}

private int startActivityMayWait(...){

...

int res = startActivity(...);

...

}

private int startActivity(...){

...

result = startActivityUnchecked(...)

...

}

private int startActivityUnchecked(...){

...

mTargetStack.startActivityLocked(...);

...

}

protected final ActivityStackSupervisor mStackSupervisor;

void startActivityLocked(...){

...

ensureActivitiesVisibleLocked(...);

...

}

final void ensureActivitiesVisibleLocked(...){

...

if (makeVisibleAndRestartIfNeeded(...)){

...

}

...

}

private boolean makeVisibleAndRestartIfNeeded(...){

...

mStackSupervisor.startSpecificActivityLocked(...);

...

}

final ActivityManagerService mService;

void startSpecificActivityLocked(...){

...

realStartActivityLocked(...);

...

mService.startProcessLocked(...);

...

}

final boolean realStartActivityLocked(...){

...

clientTransaction = ClientTransaction.obtain(app.thread,...);

clientTransaction.addCallback(LaunchActivityItem.obtain(...));

...

mService.getLifecycleManager().scheduleTransaction(clientTransaction);

...

}

void scheduleTransaction(...){

...

transaction.schedule();

...

}

private List mActivityCallbacks;

private IApplicationThread mClient;

public void addCallback(...) {

...

mActivityCallbacks.add(activityCallback);

}

public void schedule() throws RemoteException {

mClient.scheduleTransaction(this);

}

public static ClientTransaction obtain(IApplicationThread client, ...) {

...

instance.mClient = client;

...

return instance;

}

public static void main(String argv[]) {

...

Runnable r = forkSystemServer(...);

...

r.run();

...

caller = zygoteServer.runSelectLoop(abiList);

...

caller.run();

}

private static Runnable forkSystemServer(...) {

String args[] = {

...

"com.android.server.SystemServer",

};

parsedArgs = new ZygoteConnection.Arguments(args);

...

pid = Zygote.forkSystemServer(...);

...

return handleSystemServerProcess(parsedArgs);

}

private static Runnable handleSystemServerProcess(...){

...

WrapperInit.execApplication(...);

...

}

public static final Runnable zygoteInit(...) {

...

return RuntimeInit.applicationInit(...);

}

static final Runnable childZygoteInit(...) {

...

return RuntimeInit.findStaticMain(...);

}

@Override

public static void execApplication(...) {

...

command.append(" '--nice-name=").append(niceName).append("'");

...

Zygote.execShell(command.toString());

}

public static int forkSystemServer(...) {

VM_HOOKS.preFork();

int pid = nativeForkSystemServer(...);

...

VM_HOOKS.postForkCommon();

return pid;

}

public static void execShell(String command) {

String[] args = { "/system/bin/sh", "-c", command };

...

Os.execv(args[0], args);

...

}

public static void main(String[] args) {

new SystemServer().run();

}

private void run() {

...

mSystemServiceManager = new SystemServiceManager(mSystemContext);

...

startBootstrapServices();

...

startOtherServices();

...

}

private void startBootstrapServices() {

...

mActivityManagerService = mSystemServiceManager.startService(...)...;

...

mPackageManagerService = PackageManagerService.main(...);

...

}

private void startOtherServices() {

...

wm = WindowManagerService.main(...);

...

mActivityManagerService.setWindowManager(wm);

...

mActivityManagerService.systemReady(...);

...

}

public void startService(...) {

...

service.onStart();

...

}

public static final String ZYGOTE_SOCKET = "zygote";

public static final ZygoteProcess zygoteProcess =

new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);

public static final ProcessStartResult start(...) {

...

return zygoteProcess.start(...);

}

public final Process.ProcessStartResult start(...) {

...

return startViaZygote(...);

...

}

private Process.ProcessStartResult startViaZygote(...){

...

zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),...);

...

}

private ZygoteState openZygoteSocketIfNeeded(...){

...

... = ZygoteState.connect(mSocket);

...

}

public static class ZygoteState {

...

public static ZygoteState connect(LocalSocketAddress address) ... {

...

zygoteSocket.connect(address);

...

}

}

Runnable processOneCommand(ZygoteServer zygoteServer) {

...

return handleChildProc(...);

...

}

private Runnable handleChildProc(...) {

...

if (...) {

WrapperInit.execApplication(...);

throw new IllegalStateException(...);

} else {

if (!isZygote) {

return ZygoteInit.zygoteInit(...);

} else {

return ZygoteInit.childZygoteInit(...);

}

}

...

}

protected static Runnable applicationInit(...) {

...

return findStaticMain(...);

}

protected static Runnable findStaticMain(...) {

return new MethodAndArgsCaller(...);

}

static class MethodAndArgsCaller implements Runnable {

...

public void run() {

...

mMethod.invoke(null, new Object[] { mArgs });

...

}

...

}

Runnable runSelectLoop(String abiList) {

...

ZygoteConnection connection = peers.get(i);

final Runnable command = connection.processOneCommand(this);

...

}

public final int startActivity(...) {

return startActivityAsUser(...);

}

public final int startActivityAsUser(...) {

return mActivityStartController.obtainStarter(...)

....

.execute();

}

private final boolean startProcessLocked(...) {

...

final String entryPoint = "android.app.ActivityThread";

...

return startProcessLocked(..., entryPoint, ...);

}

private boolean startProcessLocked(..., String entryPoint,...){

...

final ProcessStartResult startResult = startProcess(...);

...

}

private ProcessStartResult startProcess(...) {

...

startResult = Process.start(entryPoint,...);

...

}

public final void bindApplication(...){

...

ServiceManager.initServiceCache(services);

...

}

private Activity performLaunchActivity(...) {

...

mInstrumentation.callActivityOnCreate(...);

...

}

public Activity handleLaunchActivity(...){

...

final Activity a = performLaunchActivity(...);

...

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小城交通大转型!苏州金龙助力杭州建德公交开新格局

新安江畔,密林丛生,一辆辆绿色巴士穿梭而行,杭州市首款纯电动无站立位公交车正在试运行中。 12月19日,杭州建德,23辆苏州金龙海格牌6米无站立位新能源纯电动公交车正式交付建德市公共交通运输有限公司。自此&#xff…

java虚拟机性能优化_死磕Java虚拟机-性能调优实战篇

Java命令分为如下三种1. 以java - 开头:标准参数2. 以java -X 开头:非标参数3. 以java -XX 开头:性能调优主要用这个开头的参数,但是无法找到相关参数的帮助文档,下面我教大家几个常用的命令-XX:UseSerialGC Seria…

java volatile 原子性_Java中volatile不能保证原子性的证明

Java并发编程之验证volatile不能保证原子性通过系列文章的学习,凯哥已经介绍了volatile的三大特性。1:保证可见性 2:不保证原子性 3:保证顺序。那么怎么来验证可见性呢?本文凯哥(凯哥Java:kaigejava)将通过代码演示来证…

mysql 漏洞如何修复_Mysql漏洞修复方法思路及注意事项

【系统环境】系统环境:Red Hat Enterprise Linux Server release 5.4 (Tikanga) 5.7.16 MySQL Community Server (GPL)【漏洞信息】漏洞信息报告,根据集团第三方软件扫描出对应数据库版本的漏洞信息,可以从DVE号跟当前数据库发布版本时间来判…

Java飞机大战敌机消失_Shoot 飞机大战,功能是子弹打在敌机上, 消失 且在内存中 , 小蜜蜂上同理 Games 游戏 247万源代码下载- www.pudn.com...

文件名称: Shoot下载 收藏√ [5 4 3 2 1 ]所属分类: Games开发工具: Java文件大小: 371 KB上传时间: 2015-12-01下载次数: 0提 供 者: 刘星详细说明:飞机大战,功能是子弹打在敌机上,子弹消失敌机消失且在内存中消失,打在小蜜…

日志分析告警实现java_关于Aborted connection告警日志的分析

前言:有时候,连接MySQL的会话经常会异常退出,错误日志里会看到"Got an error reading communication packets"类型的告警。本篇文章我们一起来讨论下该错误可能的原因以及如何来规避。1.状态变量Aborted_clients和Aborted_connects…

网页java在div输出内容_JS实现读取xml内容并输出到div中的方法示例

本文实例讲述了JS实现读取xml内容并输出到div中的方法。分享给大家供大家参考,具体如下:note.xml文件结构:GeorgeJohnReminderaJohnReminderGeorgeJohnReminder利用js将xml输出到div中:www.jb51.net js读取xml.aaaa{width: 30%;height: 50px;…

java枚举加载顺序_java 中类的加载顺序(转)

1、虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化2、只有在调用new方法时才会创建类的实例3、类实例创建过程:按照父子继承关系进行初始化,首先执行父类的初始化块部分,然后是父类的构造方法…

java相遇问题_两车追及或相遇问题(hdu1275)数学题

两车追及或相遇问题Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 902 Accepted Submission(s):259Problem Description外号叫“猪头三”的小学生在数学课上,经常遇到两车相遇或追及的方程题,…

java常用class类_java常用类

java常用类内部类1.成员内部类:在一个类的内部定义一个完整的类例如:外部类public class Body{内部类class Header{}}内部类可以直接访问外部类的私有成员,而且不破坏封装内部类可以为外部类提供必要的功能组件,成员内部类 在类的…

mysql 分类计数器_PHP MySQL映像计数器

我是PHP新手,一直在研究计数器.计数器很好用,但是现在我想将数字转换成图像.我创建了12张图片0-9,一个空格和一个逗号图片.我在上下搜索,以获取将数字格式转换为图像所需的提示,但没有成功.到目前为止,我所发现的就是如何仅使用文件PHP / MySQL来建立基本的计数器,以及如何使用…

java gc时会暂停运行吗,java gc 项目终止运行

当前位置:我的异常网 编程 java gc 项目终止运行java gc 项目终止运行www.myexceptions.net 网友分享于:2013-09-03 浏览:6次java gc 项目停止运行首先感谢阿宝同学的帮助,我才对这个gc算法的调整有了一定的认识,而不是停留在过…

php 取消页面一些样式,jquery如何去除样式

jquery去除样式的方法:1、使用【removeClass()】方法,代码为【removeClass(function(index,class))】;2、使用toggleClass方法,代码为【toggleClass(class)】。本教程操作环境:windows7系统、jquery3.2.1版&#xff0c…

matlab对经济指标分析,经济背景下的数据预测分析--基于matlab建模(郑铿城)

1、经济预测概述经济预测有三个要素,实际资料是预测的依据;经济理论是预测的基础;数学模型是预测的手段;经济预测的内容包括生产和资源预测,市场预测,国民收入分配预测,居民生活质量预测等。预测…

php nginx 静态资源,Nginx实践篇(1)- Nginx作为静态资源web服务 - 静态资源压缩

一、静态资源web服务1. 静态资源类型类型文件类型浏览器端渲染HTML、CSS、JS图片JEPG、GIF、PNG视频FLV、MPEG文件TXT等其他下载文件2. 静态资源服务场景-CDN二、静态资源核心配置1. 文件读取 sendfilesendfile 是一种高效传输文件的模式.sendfile设置为on表示启动高效传输文件…

php将get传参解析成数组,php解析url (parse_url) 参数成数组 (parse_str)

今天首先让我们为天津8.12大爆炸和陕西山阳山体滑坡遇难的同胞默哀3分钟,祝愿受伤的群众早日康复,脱离危险,希望国家严惩事故责任人,安抚受损群众。希望杯具以后不再发生……最近天灾人祸,大家出行一定要注意安全&…

猛将赵云java,这五位三国猛将临危救主,赵云只能排第二位,第一位大家都服...

曹洪,曹子廉。是曹操的从弟,在《三国演义》小说中,最早跟随曹操起兵,虽然战斗力没有一流战将那么强悍,但是此人在曹操起兵讨伐董卓时,曹操在荥阳被徐荣打败,坐骑丢失。正要被徐荣士兵解决的时刻…

用python画三维图、某区域的高程,python - 在PyQt中绘制具有高程和降低效果的3D矩形/多边形 - SO中文参考 - www.soinside.com...

据我所知,没有内置的PyQt 3D绘制小部件/功能,因为您只能绘制2D多边形。但我们可以创建一个自定义类来模拟3D绘画。从您的Java链接reference:Java支持3D矩形,但第三维的效果不是很明显。由于海拔较低,效果可以忽略不计。…

2024年PMP考试新考纲-PMBOK第七版-项目管理原则真题解析(续3)

马上就要进入2024年了,要参加2024年PMP一季度考试的小伙伴可以准备起来了。2024年的PMP考试将继续采用新考试大纲,考试内容包括PMBOK第六版、PMBOK第七版和敏捷实践指南,而且敏捷(或者叫混合)的项目环境将占比超过50%&…

linux 串口信息记到日志,[linux学习笔记]之一:ubuntu ch340调试备忘

[linux学习笔记]之一:ubuntu ch340调试备忘已有 2183 次阅读2016-11-8 21:52|个人分类:linux最近迷上了Linux,入了一块板。电脑使用win7ubuntu 双系统,可是调试的时候就麻烦了,ubuntu下写好sd卡镜像,调试的时候还要切换…