当前位置:   article > 正文

深入理解Android中的startActivity过程_android startactivity

android startactivity


Activity应该是我们在日常开发中最熟悉的一个组件了,当我们在应用程序中启动一个新的Activity时,实际上是进行了一系列复杂的操作。本文将尽量以简化的方式梳理Android中startActivity的关键脉络,帮助读者更好地理解Android的Activity管理机制。

一、startActivity的过程

1.1 发起startActivity请求

当应用程序调用startActivity方法时,会将请求传递给ActivityManagerService(AMS)。AMS是一个系统级服务,负责管理应用程序的生命周期、任务栈和进程。具体的调用过程为:首先,在应用程序中调用Context.startActivity(Intent)方法,传入一个Intent对象。然后,ContextImpl.startActivity()方法会将请求传递给Instrumentation.startActivity()。最后,Instrumentation.startActivity()方法会调用ActivityManagerNative.getDefault().startActivity(),将请求发送给AMS。

1.2 处理startActivity请求

AMS接收到startActivity请求后,会进行一系列的检查和准备工作,包括检查调用者的权限,解析Intent,查找目标Activity的ComponentName,确保目标Activity存在,并且可以访问,以及创建或更新任务栈,将目标Activity添加到合适的任务栈中。

1.3 创建目标Activity的进程

如果目标Activity所在的进程尚未启动,AMS会创建一个新的进程来承载目标Activity。AMS会与Zygote进程通信,请求创建一个新的进程。Zygote进程会fork出一个新的子进程,即App进程,并初始化基本的运行时环境,如创建Application对象、设置ClassLoader等。

新进程启动后,会调用其Application对象的onCreate()方法。接着,新进程会与AMS建立连接,创建一个ActivityThread对象,用于处理Activity的生命周期事件。

通过这种方式,Zygote进程确保了所有应用程序进程都是通过相同的基本环境创建的,有助于提高资源利用率和启动速度。

1.4 实例化目标Activity

在目标进程中,ActivityThread会负责实例化目标Activity。ActivityThread收到AMS的请求后,会调用performLaunchActivity()方法来创建目标Activity的实例。在performLaunchActivity()方法中,会首先调用Instrumentation.newActivity()方法来实例化目标Activity。接着,会调用目标Activity的onCreate()方法,执行Activity的初始化操作。

1.5 显示目标Activity

目标Activity实例化完成后,系统会将其添加到窗口管理器(WindowManager)中,使其可见。ActivityThread会调用handleResumeActivity()方法,准备显示目标Activity。在handleResumeActivity()方法中,会调用WindowManager.addView()方法,将目标Activity的视图添加到窗口管理器中。系统会执行视图的绘制流程,将目标Activity的内容显示到屏幕上。

1.6 处理Activity切换动画

在新的Activity呈现出来之后,系统会处理Activity之间的切换动画。这个过程由WindowManagerService(WMS)和ActivityOptions负责。WMS会获取到ActivityOptions中定义的切换动画,并进行播放,从而实现平滑的Activity切换效果。

1.7 处理返回结果

如果startActivity是使用startActivityForResult发起的,那么在新的Activity关闭后,原Activity的onActivityResult方法会被调用。在这个方法中,你可以获取到新Activity返回的数据。

1.8 处理异常

在startActivity的过程中,如果发生了异常(如Activity未找到、权限不足等),系统会抛出相应的异常。应用程序可以捕获这些异常,进行相应的错误处理。

二、startActivity的流程图

下图是来自Gityuan在startActivity启动过程分析一文中总结的流程图:
在这里插入图片描述
上图涉及到多个进程之间的通信和协作,主要包括Launcher进程、system_server进程、Zygote进程和App进程。以下是这个过程的详细步骤:

  1. Launcher进程发起startActivity请求:当用户点击桌面App图标时,Launcher进程会通过Binder IPC向system_server进程发起startActivity请求。

  2. system_server进程处理请求:system_server进程接收到请求后,首先会检查权限、解析Intent、查找目标Activity等。然后,它会向Zygote进程发送创建进程的请求。

  3. Zygote进程创建App进程:Zygote进程是Android系统的应用程序进程孵化器,负责创建新的应用程序进程。收到请求后,Zygote进程会fork出一个新的子进程,即App进程。

  4. App进程发起attachApplication请求:新创建的App进程会通过Binder IPC向system_server进程发起attachApplication请求,通知system_server进程它已经创建成功并准备好运行。

  5. system_server进程准备工作:system_server进程收到attachApplication请求后,会进行一系列准备工作,如创建任务栈、设置进程间通信通道等。准备工作完成后,system_server进程会通过Binder IPC向App进程发送scheduleLaunchActivity请求。

  6. App进程接收scheduleLaunchActivity请求:App进程的Binder线程(ApplicationThread)在收到scheduleLaunchActivity请求后,会通过Handler向主线程发送LAUNCH_ACTIVITY消息。

  7. 主线程创建Activity:主线程收到LAUNCH_ACTIVITY消息后,会通过反射机制创建目标Activity实例,并回调Activity的生命周期方法,如onCreate()onStart()onResume()等,完成Activity的初始化和显示。

三、关于startActivity过程中各个角色的介绍

3.1 ApplicationThread

ApplicationThread负责在应用程序进程中处理与系统服务(如ActivityManagerService,AMS)之间的通信以及管理应用程序组件的生命周期。实际上,ApplicationThread是ActivityThread类的一个内部类,它继承自IApplicationThread.Stub,实现了Binder IPC通信接口。下面我们详细阐述Android中的ApplicationThread:

3.1.1 实现

ApplicationThread位于android.app包中的ActivityThread类内部。它继承自IApplicationThread.Stub,实现了一系列用于Binder IPC通信的接口方法。这些方法主要用于接收来自AMS的请求,如创建Activity、暂停Activity、绑定Service等。

3.1.2 机制作用

以下是ApplicationThread的主要机制作用:

3.1.2.1 生命周期管理

ApplicationThread负责处理来自AMS的关于应用程序组件生命周期的请求。当AMS需要创建、暂停、恢复或销毁一个Activity时,它会通过Binder IPC向应用程序进程发送相应的请求。ApplicationThread会接收到这些请求,并调用相应的方法来处理这些请求。这些方法会通过Handler向主线程发送消息,主线程收到消息后会执行相应的操作,如调用Activity的onCreate()onPause()onResume()onDestroy()方法。

3.1.2.2 与AMS的通信

ApplicationThread与AMS之间的通信是通过Binder IPC实现的。AMS是一个系统级服务,负责管理应用程序的生命周期、任务栈和进程。当AMS需要与应用程序进程通信时,它会调用ApplicationThread的接口方法,如scheduleLaunchActivity()schedulePauseActivity()scheduleResumeActivity()等。这种通信机制确保了应用程序与系统服务之间的解耦和高效通信。

public final void scheduleLaunchActivity(/*参数省略*/){
	//……省略代码
	sendMessage(H.LAUNCH_ACTIVITY, r);
}
  • 1
  • 2
  • 3
  • 4

sendMessage内部使用了Hanlder,发送了一个H.LAUNCH_ACTIVITY类型的消息,然后调用handleLaunchActivity()->performLaunchActivity()方法。

3.1.2.3 处理其他请求

除了处理应用程序组件生命周期相关的请求外,ApplicationThread还负责处理其他来自AMS的请求,如绑定Service、接收广播、处理ContentProvider等。对于这些请求,ApplicationThread同样会实现相应的接口方法,并通过Handler向主线程发送消息来处理这些请求。

3.1.3 小结

ApplicationThread负责处理与系统服务(如AMS)之间的通信以及管理应用程序组件的生命周期。它作为ActivityThread类的内部类,实现了一系列用于Binder IPC通信的接口方法。

3.2 ActivityThread

ActivityThread是Android系统中一个核心组件,负责管理应用程序进程内的Activity生命周期、UI线程和消息循环。它在每个应用程序进程中都有一个实例,与ActivityManagerService(AMS)协同工作,确保应用程序组件能够正确地创建、运行和销毁。以下是ActivityThread的实现和机制作用的详细阐述:

3.2.1 实现

ActivityThread是一个Java类,位于android.app包中。它的主要成员变量包括:

  • Looper mLooper:用于处理消息循环的Looper对象。
  • Handler mH:用于处理UI线程消息的Handler对象。
  • Map<IBinder, ActivityClientRecord> mActivities:存储当前进程中所有活动的Activity的映射。
  • Map<IBinder, Service> mServices:存储当前进程中所有活动的Service的映射。
3.2.2 机制作用

以下是ActivityThread的主要机制作用:

3.2.2.1 生命周期管理

ActivityThread负责管理应用程序进程内的Activity生命周期。当AMS需要创建、暂停、恢复或销毁一个Activity时,它会通过Binder IPC向应用程序进程发送相应的请求。ActivityThread会接收到这些请求,并通过Handler向主线程发送相应的消息。主线程收到消息后,会执行相应的操作,如调用Activity的onCreate()onPause()onResume()onDestroy()方法。

3.2.2.2 UI线程

ActivityThread负责管理应用程序的UI线程(主线程)。UI线程是应用程序中负责处理用户界面事件和操作的线程,如点击、滑动等。在ActivityThread中,有一个名为mH的Handler对象,用于处理UI线程的消息。当AMS或其他组件需要与UI线程通信时,可以通过向mH发送消息来实现。

[ActivityThread.java]
private void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
3.2.2.3 消息循环

ActivityThread使用Looper对象来实现消息循环。消息循环是一种事件驱动的编程模型,用于处理来自AMS、用户界面和其他组件的事件。在ActivityThread的主线程中,会调用Looper.loop()方法来启动消息循环。这个方法会不断地从消息队列(MessageQueue)中获取消息,并分发给相应的Handler处理。这样,应用程序可以在一个线程中处理多个事件,而无需创建额外的线程。

3.2.3 小结

ActivityThread负责管理应用程序进程内的Activity生命周期、UI线程和消息循环。

3.3 将ApplicationThread和ActivityThread关联起来的过程

Client ActivityManagerService ApplicationThread ActivityThread startActivity(intent) scheduleLaunchActivity(intent) handleMessage(LAUNCH_ACTIVITY) performLaunchActivity() onCreate() onStart() onResume() Client ActivityManagerService ApplicationThread ActivityThread

时序图解释:

  1. 客户端(Client)调用 startActivity(intent),将请求发送给ActivityManagerService(AMS)。
  2. AMS根据请求,调用ApplicationThread的 scheduleLaunchActivity(intent) 方法。
  3. ApplicationThread接收到请求,将 LAUNCH_ACTIVITY 消息添加到消息队列。
  4. ActivityThread处理消息队列,处理 handleMessage(LAUNCH_ACTIVITY) 消息。
  5. ActivityThread调用 performLaunchActivity() 方法来启动Activity。
  6. 接着,ActivityThread调用客户端的 onCreate()onStart()onResume() 生命周期方法。

上文简化了实际流程中的一些细节。在实际应用中,还涉及到许多其他组件和步骤,如窗口管理器、视图系统等。这里仅展示了与AMS、ApplicationThread和ActivityThread相关的主要流程。

下面是来自Android Framework之Activity启动流程(一)一文中的详细时序图,大家有兴趣可以进一步阅读:
在这里插入图片描述

四、总结

Android中的startActivity过程涉及到Android系统的多个部分,包括应用程序、AMS、WMS、ActivityThread等。每个部分都扮演着重要的角色,共同完成了Activity的启动和切换。理解这个过程,可以帮助我们更好地理解Android的Activity管理机制,

推荐阅读

Android应用启动过程详解

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/680199
推荐阅读
相关标签
  

闽ICP备14008679号