startActivity启动过程分析和Activity生命周期

一、startActivity启动过程

在这里插入图片描述
启动流程:

  1. 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
  2. system_server进程接收到请求后,向zygote进程发送创建进程的请求;
  3. Zygote进程fork出新的子进程,即App进程;
  4. App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
  5. system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送6. scheduleLaunchActivity请求;
  6. App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
  7. 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。

官方的Activity状态转换图:
在这里插入图片描述
Activity的生命周期中只有在以下3种状态之一,才能较长时间内保持状态不变。

  • Resumed(运行状态):Activity处于前台,且用户可以与其交互。
  • Paused(暂停状态): Activity被在前台中处于半透明状态或者未覆盖全屏的其他Activity部分遮挡。 暂停的Activity不会接收用户输入,也无法执行任何代码。
  • Stopped(停止状态):Activity被完全隐藏,且对用户不可见;被视为后台Activity。 停止的Activity实例及其诸如成员变量等所有状态信息将保留,但它无法执行任何代码。

除此之外,其他状态都是过渡状态(或称为暂时状态),比如onCreate(),onStart()后很快就会调用onResume()方法。

二、生命周期

2.1 进程间通信

对于App来说,其Activity的生命周期执行是与系统进程中的ActivityManagerService有一定关系的,接下来从进程和线程的角度来分析Activity的生命周期,这里涉及到系统进程和应用进程:

system_server进程是系统进程,Java framework框架的核心载体,里面运行了大量的系统服务,比如这里提供ApplicationThreadProxy(简称ATP),ActivityManagerService(简称AMS),这个两个服务都运行在system_server进程的不同线程中,由于ATP和AMS都是基于IBinder接口,都是binder线程,binder线程的创建与销毁都是由binder驱动来决定的。

App进程是应用程序所在进程,主线程主要负责Activity/Service等组件的生命周期以及UI相关操作都运行在这个线程; 另外,每个App进程中至少会有两个binder线程 ApplicationThread(简称AT)和ActivityManagerProxy(简称AMP),除了下图中所示的线程,其实还有很多线程,比如signal catcher线程等。
在这里插入图片描述
Binder用于不同进程之间通信,由一个进程的Binder客户端向另一个进程的服务端发送事件,比如图中线程2向线程4发送事务;而handler用于同一个进程中不同线程的通信,比如图中线程4向主线程发送消息。

结合图说说Activity生命周期,比如暂停Activity的流程如下:

  • 线程1的AMS中调用线程2的ATP来发送事件;(由于同一个进程的线程间资源共享,可以相互直接调用,但需要注意多线程并发问题)
  • 线程2通过binder将暂停Activity的事件传输到App进程的线程4;
  • 线程4通过handler消息机制,将暂停Activity的消息发送给主线程;
  • 主线程在looper.loop()中循环遍历消息,当收到暂停Activity的消息(PAUSE_ACTIVITY)时,便将消息分发给ActivityThread.H.handleMessage()方法,再经过方法的层层调用,最后便会调用到Activity.onPause()方法。

这便是由AMS完成了onPause()控制,同理Activity的其他生命周期也是这么个流程来进行控制的。

2.2 App主线程

每个App都有一个主线程,大家常说主线程是ActivityThread,其实这个说法是欠妥当的,首先何为线程?一般来说Java层创建线程往往是通过继承Thread对象或者实现Runnable,再看看ActivityThread,会发现该对象并没有继承任何对象。准确说法ActivityThread是运行在主线程的对象,充当着主线程的职责。

那主线程到底是哪个呢,这个问题涉及到Linux进程与线程的理解,本质上来说大家常说的主线程就是app首次启动时创建的进程,对于Linux来说进程与线程都是一个task_struct结构体,除了是否有独立资源,并没有什么区别。

那有为何说充当着主线程的职责呢?这是由于进程在创建之初ActivityThread会为主线程创建Looper对象,这个便是用来维护Activity的生命周期。

2.3 枢纽中心

Activity的生命周期,都是其他线程通过handler发送消息给主线程,那么主线程中的ActivityThread的内部类H控制整个核心消息处理机制,通过H.handleMessage()来控制Activity的生命周期,在H类中共定义了50种消息。

private class H extends Handler {
   
  public static final int LAUNCH_ACTIVITY         = 100;
  public static final int PAUSE_ACTIVITY          = 101;
  public static final int PAUSE_ACTIVITY_FINISHING= 102;
  public static final int STOP_ACTIVITY_SHOW      = 103;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Activity启动模式是Android应用程序中非常重要的概念,它决定了Activity的启动方式和生命周期的管理方式。在Android中,Activity启动模式主要有以下几种: 1. standard:标准模式。默认情况下,每次启动Activity时都会创建一个新实例,并放入任务栈中。如果该Activity已经存在任务栈中,则会将该Activity放到栈顶,并重新调用其onCreate()方法。 2. singleTop:栈顶复用模式。如果新启动的Activity已经存在任务栈的栈顶,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并调用其onNewIntent()方法。如果新启动的Activity不在栈顶,则会创建新实例,并将其放到任务栈的栈顶。 3. singleTask:栈内复用模式。如果新启动的Activity已经存在任务栈中,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并将其上面的Activity全部出栈,调用其onNewIntent()方法。如果新启动的Activity不存在任务栈中,则会创建新实例,并放到任务栈的栈顶。 4. singleInstance:单例模式。在一个新的任务栈中创建Activity,并且该任务栈中只有该Activity实例。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。 下面是Activity的源码分析: 1. standard模式 在Activity的源码中,标准模式是默认的启动模式。当我们使用startActivity()方法启动一个Activity时,会调用ActivityStackSupervisor类中的startActivityLocked()方法。在该方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会将当前Activity放到该任务栈的栈顶,并调用其onCreate()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 2. singleTop模式 当我们在Manifest文件中设置Activity的启动模式为singleTop时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈,并判断当前Activity是否在栈顶。如果在栈顶,则会调用其onNewIntent()方法。如果不在栈顶,则会创建一个新的实例,并放到该任务栈的栈顶。 3. singleTask模式 当我们在Manifest文件中设置Activity的启动模式为singleTask时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会找到该任务栈中的栈顶Activity,并将其上面的所有Activity出栈。然后将当前Activity放到该任务栈的栈顶,并调用其onNewIntent()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 4. singleInstance模式 当我们在Manifest文件中设置Activity的启动模式为singleInstance时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值