前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解Android中的startActivity过程

深入理解Android中的startActivity过程

作者头像
陆业聪
发布2024-07-23 18:19:58
720
发布2024-07-23 18:19:58
举报
文章被收录于专栏:大前端修炼手册

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启动过程分析》(https://gityuan.com/2016/03/12/start-activity/)一文中总结的流程图:

上图涉及到多个进程之间的通信和协作,主要包括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()等。这种通信机制确保了应用程序与系统服务之间的解耦和高效通信。

代码语言:javascript
复制
public final void scheduleLaunchActivity(/*参数省略*/){
 //……省略代码
 sendMessage(H.LAUNCH_ACTIVITY, r);
}

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发送消息来实现。

代码语言:javascript
复制
[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);
    }
3.2.2.3 消息循环

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

3.2.3 小结

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

3.3 将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启动流程(一)》(https://pomelojiang.github.io/android_framework_start_activity_1)一文中的详细时序图,大家有兴趣可以进一步阅读:

四、总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陆业聪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、startActivity的过程
    • 1.1 发起startActivity请求
      • 1.2 处理startActivity请求
        • 1.3 创建目标Activity的进程
          • 1.4 实例化目标Activity
            • 1.5 显示目标Activity
              • 1.6 处理Activity切换动画
                • 1.7 处理返回结果
                  • 1.8 处理异常
                  • 二、startActivity的流程图
                  • 三、关于startActivity过程中各个角色的介绍
                    • 3.1 ApplicationThread
                      • 3.1.1 实现
                      • 3.1.2 机制作用
                      • 3.1.3 小结
                    • 3.2 ActivityThread
                      • 3.2.1 实现
                      • 3.2.2 机制作用
                      • 3.2.3 小结
                    • 3.3 将ApplicationThread和ActivityThread关联起来的过程
                    • 四、总结
                    相关产品与服务
                    消息队列 CMQ
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档