Activity的启动流程

2023-05-16

总的流程图:


1. 进程A与AMS的交互过程
此处以跨进程启动Activity分析一下源码流程: 

A调用startActivity时,需要与AMS交互,此时需要需要获取到AMS的代理对象Binder也就是上图的AMP,通过ActivityManagerNative.getDefault()获得,并调用AMP的startActivity方法,然后会通过mRemote.transact方法进行Binder通信,在AMS的onTransact方法里面会获取到请求的Activity参数信息:

mRemote.transact(START_ACTIVITY_TRANSACTION,data,reply,0);
...
 
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags){
      switch(code){
   case START_ACTIVITY_TRANSACTION:{        startActivity(app,callingPackage,intent,...)
   }
}}


AMS里面的startActivity方法最主要会去调用startSpecificActivityLocked函数,在此函数里面会去判断目标进程是否已经存在,并且目标向AMS注册过它自己的ApplicationThread也就是上图ATP代理对象,如果这两个条件都满足会去调用realStartActivityLocked方法,这个方法我们后面再看。如果上述条件不满足时,会去调用mService.startProcessLocked(r.processName,...)方法启动进程。

2. AMS启动目标进程B


startProcessLocked方法首先调用Process.start("android.app.ActivityThread",)方法会向Zygote发送一个启动进程的请求,并告知Zygote进程启动之后,加载ActivityThread这个类的入口main函数,启动完成后返回进程的pid,并向AMS的Handler发送一个延迟消息,为的是要求目标进程启动后,10秒钟内需要向AMS报告,不然的话AMS就会清除目标进程的相关信息。

 

Process.start方法会去调用startViaZygote(processClass,)函数,这个函数主要做了两件事,一件就是打开通往Zygote的Socket,第二件事就是通过Socket发送启动进程参数。

Zygote端主要逻辑是在runOnce函数,函数内调用Zygote.forkAndSpecialize(...)创建子进程,创建完成之后就分别在父进程和子进程里面做各自的事情

1) 父进程通过hanleParentProc(pid)把子进程的pid通过Socket发送给AMS
2)子进程调用handleChildProc函数,做一些通用的初始化,比如启用Binder机制;执行应用程序的入口函数,也就是ActivityThread的Main函数

ActivityThread的main函数,里面会创建一个ActivityThread对象,并调用thread.attach(false),为的是向AMS报到,上面第一条里面有提到。
attach方法里面,其实是一个跨进程的调用,首先通过

IActivityManager mgr = ActivityManagerNative.getDefault();


获取到AMS的Binder代理对象,然后调用

mgr.attachApplication(mAppThread);

mAppThread是应用端的一个Binder对象ApplicationThread,也就是最上面一张图的ATP,这样AMS端就可以调用应用端了。

attachApplication方法里面,最主要有两个方法,一个是通过传入的ApplicationThread对象,调用bindApplication初始化Application对象,另一个就是通过
 

mStactSupervisor.attachApplicationLoacked(app);

初始化挂起的Activity对象。

在attachApplicationLoacked函数里,会调用

ActivityRecord hr = stack.topRunningActivityLocked(null);


其中要明白AMS里面有两个栈,一个是Launch桌面栈,一个就是非桌面栈mFocusedStack,此处的stack就是mFocusedStack,它会将栈顶的ActivityRecord返回出来,我们的目标Activity早就放置在了栈顶,只是一直没有初始化。然后调用

realStartActivityLocked(hr,app,true,true);

方法,来启动Activity,如果我们不是启动另外一个进程,而是同一进程,那么这第二大部分就不会存在了,而是直接调用realStartActivityLocked方法。

3. 应用端Activity启动的几个步骤
realStartActivityLocked函数会调用app.thread.scheduleLaunchActivity(new Intent(r.intent),...);也就是通过之前注册的Binder对象ATP,调用scheduleLaunchActivity函数,在scheduleLaunchActivity函数里面:

ActivityClientRecord r = new ActivityClientRecord();
...
sendMessage(H.LAUNCH_ACTIVITY,r);

封装了一个ActivityClientRecord消息,然后丢到主线程的Handler(mH)里。

在主线程里面

final ActivityClientRecord r = (ActivityClientRecord)msg.obj ;
r.packageInfo = getPackageInfoNoCheck(...);
handleLaunchActivity(r,null);

getPackageInfoNoCheck 函数主要是用来生成一个LoadedApk对象,它用来保存我们的apk信息,因为后面我们需要一个ClassLoader去加载Apk里面的Activity类,所以这里提前准备好。

handleLaunchActivity里面分为两个部分,一个是performLaunchActivity函数,一个是handleResumeActivity函数。
1) performLaunchActivity

Activity activity = mInstrumentation.newActivity(...);
 
//返回之前创建好的
Application app = r.packageInfo.makeApplication(false,mInstrumentation);
 
//生成ContextImpl
Context appContext = createBaseContextForActivity(r,activity);
 
//给activity绑定上下文和一些初始化的工作,如createPhoneWindow
activity.attach(appContext,...);
 
mInstrumentation.callActivityOnCreate(activity,r.state); //生命周期的OnCreate
 
activity.performStart();    //生命周期的OnStart
 
return activity


2) handleResumeActivity:

-> r.activity.performResume()     
   -> mInstrumentation.callActivityOnResume(this);
     -> activity.onResume()

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Activity的启动流程 的相关文章

  • android源码编译-如何在Mac中卸载openjdk15

    说明 之前在mac上使用intellij idea时 xff0c 由于没有在Mac上安装过jdk xff0c 所以就在intellij idea中下载了openjdk15版本 后来觉得想要换一个旧点的版本 xff0c 就想卸载了openjd
  • Mac OS查看和设置JAVA_HOME

    下载java https www java com zh CN download 1 查看JAVA版本 打开Mac电脑 xff0c 查看JAVA版本 xff0c 打开终端Terminal xff0c 通过命令行查看笔者的java版本 xff
  • Android源码编译–jdk版本查询

    2 1 Android源码所需JDK版本 根参考资料 1 的说明 xff0c 在android src build core main mk中对jdk的版本进行查询 xff0c 以确定当前系统是否安装了特定版本的jdk xff0c 因此可以
  • android源码编译 ninja: build stopped: subcommand failed.

    接着编译 make j8 线程加多少个具体看机器配置 xff0c 问题也最可能是这一步骤引起的 xff0c 如果是虚拟机的话 xff0c 建议不要加线程 xff0c 直接使用make执行
  • Ubuntu环境下完美安装python模块numpy,scipy,matplotlib

    不同的ubuntu版本安装过这三个模块几次了 xff0c 然而总是出现各种问题 xff0c 最近一次是在ubuntu 16 04 LTS server版本安装的 xff0c 总的来说安装的比较顺利 先把pip安装好 sudo apt get
  • prebuilts/misc/darwin-x86/bison/bison: Bad CPU type in executable

    方案一 cd external bison touch patch high sierra patch vim patch high sierra patch With format string strictness High Sierr
  • android源码编译 坑

    bash lunch command not found 先调用 build envsetup sh 再执行 lunch Can not find SDK Can not find SDK 10 6 at Developer SDKs Ma
  • 获取当前MacOSX SDK

    xcrun show sdk path 打印出 Library Developer CommandLineTools SDKs MacOSX sdk xcrun show sdk version 打印出 10 15 4 xcode sele
  • Mac OS10.12 编译Android源码8.1

    内容 介绍mac os10 12拉取android源码 xff0c 并且编译后 xff0c 刷入手机的过程 下载的rom是android 8 1 xff0c 手机是pixel 准备工作 硬盘大小 本人Mac磁盘空间只有256GB xff0c
  • android源码 xcode版本,【Android】AOSP源码下载及编译 for mac

    本文记录了AOSP在Mac系统上下载和编译的过程 采用的系统是 macOS 10 13 1 所使用的AOSP分支是 android 8 1 0 r7 系统预留空间 大于200G 一 环境配置 环境配置 xff0c 官网给出了非常全的教程 x
  • (Android 9.0)Activity启动流程源码分析

    前言 熟悉Activity的启动流程和运行原理是一个合格的应用开发人员所应该具备的基本素质 xff0c 其重要程度就不多做描述了 同时 xff0c 知识栈应该不断的更新 xff0c 最新发布的Android 9 0版本相较于之前的几个版本也
  • Lifecycle 源码详解

    Lifecycle 是 Jetpack 整个家族体系内最为基础的内容之一 xff0c 正是因为有了 Lifecycle 的存在 xff0c 使得如今开发者搭建依赖于生命周期变化的业务逻辑变得简单高效了许多 xff0c 使得我们可以用一种统一
  • git常用命令

    1 拉取远程所有分支 git clone xxx git branch r grep v 39 gt 39 while read remote do git branch track 34 remote origin 34 34 remot
  • Android应用启动流程分析

    1 前言 网上看过很多Activity启动过程的源码解析 xff0c 很多文章会贴上一大段代码 xff0c 然后从startActivity 函数开始深究整个源码的调用栈 个人感觉这类文章代码细节太多 xff0c 反而容易迷失在源码调用之中
  • 从一个分支cherry-pick多个commit到其他分支

    在branch1开发 xff0c 进行多个提交 xff0c 这是切换到branch2 xff0c 想把之前branch1分支提交的commit都 复制 过来 xff0c 怎么办 xff1f 单个commit只需要git cherry pic
  • IntWritable详解

    1 Hadoop数据类型如下图 xff1a 由上图的Writable层次结构图可以看到绝大多数的数据类型都实现了Writable WritableComparable接口 xff0c 在此先分析一下这两个接口情况 自顶下下逐步分析 Writ
  • 线程池源码剖析

    线程池 xff08 英语 xff1a thread pool xff09 xff1a 一种线程使用模式 线程过多会带来调度开销 xff0c 进而影响缓存局部性和整体性能 而线程池维护着多个线程 xff0c 等待着监督管理者分配可并发执行的任
  • Java 设计模式之装饰者模式

    一 了解装饰者模式 1 1 什么是装饰者模式 装饰者模式指的是在不必改变原类文件和使用继承的情况下 xff0c 动态地扩展一个对象的功能 它是通过创建一个包装对象 xff0c 也就是装饰者来包裹真实的对象 所以装饰者可以动态地将责任附加到对
  • Java 设计模式之策略模式

    一 了解策略模式 1 1 什么是策略模式 策略模式 Strategy Pattern 是指对一系列的算法定义 xff0c 并将每一个算法封装起来 xff0c 而且使它们还可以相互替换 此模式让算法的变化独立于使用算法的客户 1 2 策略模式
  • Java 设计模式之适配器模式

    一 了解适配器模式 1 1 什么是适配器模式 适配器模式将一个类的接口 xff0c 转换成客户期望的另一个接口 适配器让原来接口不兼容的类可以合作无间 适配器模式有两种 xff1a 对象 适配器和 类 适配器 这个模式可以通过创建适配器进行

随机推荐

  • 责任链模式

    责任链模式的定义与特点 责任链模式的定义 xff1a 使多个对象都有机会处理请求 xff0c 从而避免请求的发送者和接受者之间的耦合关系 xff0c 将这个对象连成一条链 xff0c 并沿着这条链传递该请求 xff0c 直到有一个对象处理他
  • java设计模式-桥接模式

    桥接模式定义 桥接模式 xff08 Bridge Pattern xff09 xff0c 将抽象部分与它的实现部分分离 xff0c 使它们都可以独立地变化 更容易理解的表述是 xff1a 实现系统可从多种维度分类 xff0c 桥接模式将各维
  • java设计模式-状态模式

    1 状态模式的定义和特点 状态 xff08 State xff09 模式的定义 xff1a 对有状态的对象 xff0c 把复杂的 判断逻辑 提取到不同的状态对象中 xff0c 允许状态对象在其内部状态发生改变时改变其行为 状态模式是一种对象
  • java设计模式-命令模式

    18 xff0c 命令模式 18 1 命令模式的定义和特点 命令 xff08 Command xff09 模式的定义如下 xff1a 将一个请求封装为一个对象 xff0c 使发出请求的责任和执行请求的责任分割开 这样两者之间通过命令对象进行
  • java设计模式-代理模式

    17 xff0c 代理模式 17 1 代理模式的定义和特点 代理模式的定义 xff1a 由于某些原因需要给某对象提供一个代理以控制对该对象的访问 这时 xff0c 访问对象不适合或者不能直接引用目标对象 xff0c 代理对象作为访问对象和目
  • 工厂方法模式

    概念定义 工厂方法 Factory Method 模式 xff0c 又称多态工厂 Polymorphic Factory 模式或虚拟构造器 Virtual Constructor 模式 工厂方法模式通过定义工厂抽象父类 或接口 负责定义创建
  • TextFuseNet: Scene Text Detection with Richer Fused Features论文阅读

    TextFuseNet Scene Text Detection with Richer Fused Features 利用更丰富的特征融合进行场景文本检测 代码 xff1a https github com ying09 TextFuse
  • JUC原子类: CAS, Unsafe和原子类详解

    CAS 线程安全的实现方法包含 互斥同步 synchronized 和 ReentrantLock非阻塞同步 CAS AtomicXXXX无同步方案 栈封闭 xff0c Thread Local xff0c 可重入代码 什么是CAS CAS
  • OKHttp中的责任链模式

    一 什么是责任链模式 责任链 xff0c 顾名思义是将多个节点通过链条的方式连接起来 xff0c 每一个节点相当于一个对象 xff0c 而每一个对象层层相关 xff0c 直接或者间接引用下一个对象 xff08 节点 xff09 xff1b
  • android bugly关于混淆后如何知道正确代码

    bugly xff1a 腾讯自制 xff0c 是个4 xff0c 5句代码就能简单加入在线更新 捕获异常的好功能 xff0c 后台也是使用腾讯的 Android混淆 xff1a 启用一个配置 xff0c 把所有变量 类名改成 34 a 34
  • 大康Dacom Athlete+蓝牙耳机与手机配对上的原因及解决办法:

    1 原因 xff1a 蓝牙耳机没有进入配对模式 解决办法 xff1a 蓝牙耳机都有一个功能键 xff0c 长按听到开机提示音后不要松手 xff0c 继续长按 xff0c 直至听到进入配对模式提示音或者 滴 的提示音 xff0c 此时蓝红等交
  • android查看编译后的class文件

    其查看目录如下 然后在硬盘文件中打开 xff0c 可以看到详细的class文件列表
  • socket的shutdownInput和shutdownOutput

    虽然在大多数的时候可以直接使用Socket类或输入输出流的close方法关闭网络连接 xff0c 但有时我们只希望关闭OutputStream或InputStream xff0c 而在关闭输入输出流的同时 xff0c 并不关闭网络连接 这就
  • 使用广播接收器时,onReceive 会多次执行

    原因一 xff1a 没有在onDestory中调用解注册 unregisterReceiver 原因二 xff1a BroadcastReceiver变量所在的Activity或者Fragment被创建的多次 xff0c 形成多个对象
  • Android Studio自动生成单例代码

    AS中有可以自己设置代码模板 xff0c 使用起来简单方便 同样的 xff0c 单例类的代码样式统一 xff0c 除了类名外全部一致 所以使用模板更加方便 在设置中的Editor Live Template中新建模板 xff0c 然后把单例
  • android:excludeFromRecents 属性需要注意的小地方

    在 Android 系统中 xff0c 如果我们不想某个 Activity 出现在 Recent screens 中 xff0c 可以设置 lt activity gt 属性 android excludeFromRecents 为 tru
  • G.711编码原理

    目录 参考概述G 711原理总结 1 参考 1 wikipedia A law algorithm 2 github com quatanium foscam ios sdk 3 charybdis G711算法学习 2 概述 本文目的 x
  • RxJava 之Consumer和Action的使用

    在之前的RxJava中已经讲到创建观察者的代码如下 xff1a 创建观察者 Observer lt String gt observer 61 new Observer lt String gt 64 Override public voi
  • JAVA中枚举如何保证线程安全

    枚举类型到底是什么类呢 xff1f 是enum吗 xff1f 明显不是 xff0c enum就和class一样 xff0c 只是一个关键字 xff0c 他并不是一个类 xff0c 那么枚举是由什么类维护的呢 xff0c 首先写一个简单的枚举
  • Activity的启动流程

    总的流程图 xff1a 1 进程A与AMS的交互过程 此处以跨进程启动Activity分析一下源码流程 xff1a A调用startActivity时 xff0c 需要与AMS交互 xff0c 此时需要需要获取到AMS的代理对象Binder