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,一经查实,立即删除!

相关文章

UC浏览器屏幕亮度在哪设置 UC浏览器屏幕亮度调节方法2019

UC浏览器是可以调节屏幕亮度的,大家可以根据自己白天和晚上的浏览习惯去设置,下面,我们来看看UC浏览器屏幕亮度调节方法,希望能够帮助到大家。 UC浏览器屏幕亮度在哪设置 打开手机,在手机桌面找到UC浏览器&#xff0…

java6虚拟机_Java 虚拟机之六:javap工具

一:简介javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码。通过它,我们可以对照源代码和字节码,从而了解很多编译器内部的工作。javap命令的常用参数有:-l 打印行和本地变量表-public 只显示公共类和成…

搜狐视频app如何设置仅自己可看我的关注列表

播放器软件很多,本文播放器家园网小编给大家推荐搜狐视频。搜狐视频是当下非常流行常用的视频播放器,拥有安卓版、pc版、苹果版等适用于不同设备用户,拥有海量最新最热视频资源,精彩视频第一时间上新提醒,支持在线下载…

java中修改密码_java怎样修改用户名密码?

展开全部package changepassword;import java.util.Scanner;public class Administrator{String name;//姓名String password;//密码String inputpass;//判断是否正确的密码String newpassword;//再次输入密码String repassword;//第2输入的密码//String admin"";St…

PP视频如何设置关闭的时候直接退出程序

很多人都使用PP视频,小编给大家分享一下PP视频如何设置关闭的时候直接退出程序相关内容。如果大家还没有注册账号,那么可以注册一个,新用户还有vip奖励,当然一般也就是奖励3天或者7天的时长,直接送终身vip是不可能的&a…

java oo 封装_Java从小白到入门,Day6。JAVAOO-封装

封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一种信息隐藏技术,在java中…

腾讯视频如何设置画面对比度方面的内容

本文给大家整理了帮我下载一个腾讯视频_腾讯视频如何设置画面对比度方面的内容。腾讯视频为用户提供电影、电视剧、综艺、动漫、娱乐、热点资讯等内容,视频播放清晰流畅,操作界面简单友好。优质的正版高清视频内容、贴心的生活服务满足用户“悦享品质、时…

java 并发 变量_实例讲解Java并发编程之变量

编写线程安全需要关心的:1.共享的变量2.可变的变量共享意味着多个线程可以同时访问,可变意味着其值在生命周期可以改变。例如以下count 变量://线程不安全的类public class UnsafeCount {private int count 0; //该变量是共享的public vo…

腾讯视频下载电脑_腾讯视频如何设置允许腾讯视频驻留功能

本文给大家整理了腾讯视频下载电脑_腾讯视频如何设置允许腾讯视频驻留功能方面的内容。腾讯视频不断实践"三网合一"的使命,现已覆盖互联网、电视、移动三大终端,兼具影视、综艺、资讯三大内容形态,贯通视频内容制作、播出、发行三大…

java plug机制_【maven实战】20-插件解析机制

插件仓库:与依赖构件一样,插件构件同样基于坐标存储在maven仓库中,在需要的时候maven会从本地仓库中查找插件,如果不存在则从远程仓库查找。找到插件后在下载到本地仓库使用。值得一提的是maven会区别对待依赖的远程仓库与插件的远程仓库。当…

ie8浏览器自定义工具栏设置教程

ie8浏览器自定义工具栏设置教程 ie8浏览器自定义工具栏怎么设置?在使用IE8的网友知道,在安装IE8之后会发现IE8的工具栏中的按钮非常少,明显的不便于我们平时的上网操作。所以我们有必要根据自己的需求,把一些能够经常使用的按钮添加到工具栏…

java servlet 获取mac地址_Java开发网 - 请教大家几个关于servlet取ip和mac地址的问题~~!...

//Java获得CPU序列号和网卡Mac地址/*利用Runtime call操作系统的命令,具体的命令取决于不同的操作系统,注意不要调用Runtime.getRuntime().exec(String)接口,要用Runtime.getRuntime().exec(String[])这个接口,不然复杂命令的执行…

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

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

手机搜狗浏览器怎么样

核心提示:手机搜狗浏览器怎么样 手机搜狗浏览器怎么样 搜狗浏览器安卓版,它是搜狗官方针对android平台上而最新推出的一款安卓手机浏览器,支持同步搜狗电脑浏览器收藏,清晰简洁,享家纯真,让你的手机上网更…

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

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

让IE浏览器提示下载或直接打开word文档

核心提示:点击一个指向.doc类型的文件后,怎样不直接在IE里打开,而是弹出一个对话框提示用户想下载还是打开。让IE浏览器提示下载或直接打开word文档 点击一个指向.doc类型的文件后,怎样不直接在IE里打开,而是弹出一个…

2345王牌浏览器九宫格个性化设置

核心提示:2345王牌浏览器九宫格中的每个小窗体显示的网址,都可以进行个性化定制。 2345王牌浏览器九宫格中的每个小窗体显示的网址,都可以进行个性化定制。可以单击 2345王牌浏览器九宫格个性化设置 对某一网页进行编辑 。 可以修改你想要…

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

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

搜狐视频怎么清除应用缓存

今天继续给大家分享搜狐视频方面的内容。搜狐视频播放器是播放器家园网小编用过最好用的一款,在这里能够不同类型的电视剧和电影,都是采用了4K级高清画质,让你随时感受到电影级别的视觉盛宴!搜狐视频客户端支持边下载边观看,云同步…

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

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