android源码宇宙-activity启动源码

简介: android源码宇宙-activity启动源码

源码


关键类说明

1、ActivityRecord

Activity栈中的一个节点,用于展示一个Activity

它集成了WindowToken实现了WindowManagerService中的一个接口

image.png

既然如此顺便看看WindowToken吧

image.png


ActivityTaskSupervisor

用来替代ActivityStackSupervisor

image.png


Instrumentation

这东西是ActivityThread中的一个变量

它可以作为一个测试框架的根基,因为它是先于我们的Application和Activity启动的,所以它可以监听到我们创建Activity和Application操作。

android是支持自定义Instrumentation的,可以通过继承Instrumentation重写里面的方法实现监听

顺手找了一篇参考文章:blog.csdn.net/weixin_4235…


启动过程源码

  1. startActivity方法

image.png

  1. startActivityForResult方法

最终会走到Instrumentation.execStartActivity方法

image.png

  1. Instrumentation.execStartActivity方法

ActivityTaskManager.getService()返回结果就是IActivityTaskManager类型

需要说明的是本方法中最后一步调用的checkStartActivityResult方法可以根据返回的result判断启动activity的结果

checkStartActivityResult方法的实现可以查看  附1中内容

image.png

这里的ActivityTaskManager.getService()要说明一下,它最终调用到了ActivityTaskManager中的单例,然后获取binder调用接口

image.png

所以这里的ActivityTaskManager.getService().startActivity实际上就是ActivityTaskManagerService.startActivity


  1. ActivityTaskManagerService.startActivity

image.png

  1. startActivityAsUser

image.png

  1. ActivityStarter.execute

这里负责执行启动逻辑

image.png

image.png

image.png

  1. executeRequest

代码巨长,关键代码再结尾处startActivityUnchecked

image.png

  1. startActivityUnchecked
  2. startActivityInner
  3. Task.startActivityLocked
  4. Task.resumeTopActivityUncheckedLocked
  5. ActivityTaskSupervisor.startSpecificActivity
  6. ActivityTaskSupervisor.realStartActivityLocked
  7. ClientTransaction.addCallback
  8. ClientLifecycleManager.scheduleTransaction

mService.getLifecycleManager().scheduleTransaction(clientTransaction)

  1. ClientTransaction.schedule
  2. IApplicationThread.scheduleTransaction

实际类型是ApplicationThread.scheduleTransaction

image.png

  1. ApplicationThread.H.sendMessage()
  2. TransactionExecutor.execute

mTransactionExecutor.execute(transaction);

  1. ActivityThread.handleLaunchActivity

image.png

  1. ActivityThread.performLaunchActivity

createBaseContextForActivity方法的说明见:附2

下图中的newActivity用来创建Activity对象,实际上如果我们的Application如果没有创建,它会连带Application一起创建。但是似乎这个Application的创建并没有意义,只是个站位作用。

image.png

下图中appContext.setOuterContext(activity);方法,将我们的的activity对象赋值给ContextImpl,目的是让他们产生关联。

在Activity.attach方法中,只做了一件事,就是调用onAttachFragment方法来初始化Fragment

makeApplication方法的说明见附3

image.png

image.png

  1. ActivityThread.callActivityOnCreate方法

这个方法过后逻辑终于又转到了Activity中

image.png

  1. 最终方法会调用到performCreate方法

image.png

本节参考:www.jianshu.com/p/e875f8bde…


总结


Activity启动过程,首先会调用startActivity,最终一定会调用到Activity.startActivityForResult方法。然后会调用Instrucment.execStartActivity方法并且会获取调用ActivityThread.getApplicationThread方法获取IApplicationThread对象,IApplicationThread是一个Binder对象,它是应用进程和atms沟通的桥梁。

调用完execStartActivity方法后,会获取atms实例,然后调用atms.startActivity方法,这就完成了应用和atms的通信,程序逻辑转换到了atms中。在atms进行一大堆操作后会调用IApplicationThread的方法回调到应用进程,执行activity页面的启动工作。

atms处理完成后会调用ApplicationThread.scheduleTransaction方法,因为IApplicationThread是一个Binder对象,所以这个方法将逻辑从atms中转回到应用逻辑中。

回到应用中处理的逻辑是这样的,首先通过ActivityThread.H发送一条handler消息,告诉主线程需要启动activity。最终会将逻辑调用到ActivityThread.handleLaunchActivity方法,在Instrumentaction中使用反射创建Activity对象实例,并调用Activity.attach方法,后面会再次调用到Instrumentation.callActivityOnCreate方法,从这里就进入了activity的生命周期了。

activity的启动过程一共有两次Binder通信,

  1. 用于进程调用ActivityTaskManagerService.startActivity,代码进入atms进程中执行
  2. ClientTransaction类中IApplicationThread.scheduleTransaction,atms调用应用进程的Binder让Activity启动逻辑回到应用进程



1、Instrumentation.checkStartActivityResult方法

@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static void checkStartActivityResult(int res, Object intent) {
    if (!ActivityManager.isStartResultFatalError(res)) {
        return;
    }
    switch (res) {
        case ActivityManager.START_INTENT_NOT_RESOLVED:
        case ActivityManager.START_CLASS_NOT_FOUND:
        if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
        throw new ActivityNotFoundException(
            "Unable to find explicit activity class "
            + ((Intent)intent).getComponent().toShortString()
            + "; have you declared this activity in your AndroidManifest.xml?");
        throw new ActivityNotFoundException(
            "No Activity found to handle " + intent);
        case ActivityManager.START_PERMISSION_DENIED:
        throw new SecurityException("Not allowed to start activity "
                                    + intent);
        case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
        throw new AndroidRuntimeException(
            "FORWARD_RESULT_FLAG used while also requesting a result");
        case ActivityManager.START_NOT_ACTIVITY:
        throw new IllegalArgumentException(
            "PendingIntent is not an activity");
        case ActivityManager.START_NOT_VOICE_COMPATIBLE:
        throw new SecurityException(
            "Starting under voice control not allowed for: " + intent);
        case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
        throw new IllegalStateException(
            "Session calling startVoiceActivity does not match active session");
        case ActivityManager.START_VOICE_HIDDEN_SESSION:
        throw new IllegalStateException(
            "Cannot start voice activity on a hidden session");
        case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
        throw new IllegalStateException(
            "Session calling startAssistantActivity does not match active session");
        case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
        throw new IllegalStateException(
            "Cannot start assistant activity on a hidden session");
        case ActivityManager.START_CANCELED:
        throw new AndroidRuntimeException("Activity could not be started for "
                                          + intent);
        default:
        throw new AndroidRuntimeException("Unknown error code "
                                          + res + " when starting " + intent);
    }
    }
复制代码


2、ActivityThread.createBaseContextForActivity是如何创建上下文的

image.png


3、ActivityThread.performLaunchActivity方法中的makeApplication是如何工作的

  1. makeApplication方法

makeApplication方法在LoadedApk中

下图中的mInstrumentation.newApplication是下面要看的重点

image.png

这里的callApplicationOnCreate是下一步要看的重点

image.png

  1. Instrumentation.newApplication创建Application对象

这一步可以跳过,直接看第3步 Application.attach方法主要是调用attachBaseContext方法,并且将LoadedApk对象赋值给Application。

image.png

  1. Instrumentation.callApplicationOnCreate方法

这个方法就更简单了,直接就调用Application.onCreate,这样Application的创建和launch就结束了

image.png


4、流程图

找到一张不错的代码流程图,是低于安卓10版本的流程图,和高于android10的流程90%相似,所以拿来主义了。

流程图出处见结尾参考文章

image.png


Intent传输数据不能超过1mb原因分析

  1. 由于Activity通过intent传值,是通过App进程将intent携带的数据传输到AMS进程,最终通过Binder事务缓冲区完成数据传输
  2. 目前Binder事务缓冲区的大小固定有限,目前为1MB,进程中正在处理的所有事务共享
  3. 由于此限制是进程级别而不是Activity级别的限制,因此这些事务包括应用中的所有 binder 事务,超过大小限制时,将引发TransactionTooLargeException。

见参考4


5、onCreate后的生命周期

主要是onResume,参见WindowManager中的描述



相关文章
|
18天前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
69 6
|
19天前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
24 3
|
20天前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
17 3
|
19天前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
16 0
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
讲解Activity的启动流程了,Activity的启动流程相对复杂一下,涉及到了Activity中的生命周期方法,涉及到了Android体系的CS模式,涉及到了Android中进程通讯Binder机制等等, 首先介绍一下Activity,这里引用一下Android guide中对Activity的介绍:
49 4
|
2月前
|
Android开发 开发者
Android面试之Activity启动流程简述
每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
46 0
|
3月前
|
开发工具 uml git
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
本文分享了下载AOSP源码的方法,包括如何使用repo工具和处理常见的repo sync错误,以及配置Python环境以确保顺利同步特定版本的AOSP代码。
396 0
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
|
3月前
|
开发工具 Android开发 git
全志H713 Android 11 :给AOSP源码,新增一个Product
本文介绍了在全志H713 Android 11平台上新增名为myboard的产品的步骤,包括创建新的device目录、编辑配置文件、新增内核配置、记录差异列表以及编译kernel和Android系统的详细过程。
97 0
|
2天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
1天前
|
存储 XML JSON
探索安卓开发:从新手到专家的旅程
【10月更文挑战第36天】在这篇文章中,我们将一起踏上一段激动人心的旅程,从零基础开始,逐步深入安卓开发的奥秘。无论你是编程新手,还是希望扩展技能的老手,这里都有适合你的知识宝藏等待发掘。通过实际的代码示例和深入浅出的解释,我们将解锁安卓开发的关键技能,让你能够构建自己的应用程序,甚至贡献于开源社区。准备好了吗?让我们开始吧!
9 2
下一篇
无影云桌面