Android面试题之activity启动流程

简介: 该文探讨了Android应用启动和Activity管理服务(AMS)的工作原理。从Launcher启动应用开始,涉及Binder机制、AMS回调、进程创建、Application和Activity的生命周期。文中详细阐述了AMS处理流程,包括创建ClassLoader、加载APK、启动Activity的步骤,以及权限校验和启动模式判断。此外,还补充了activity启动流程中AMS的部分细节。欲了解更多内容,可关注公众号“AntDream”。

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

Launcher -> AMS

activity -> instrumentation -> AMS

AMS处理

Launcher应用启动新的应用

1、 启动activity,通过Binder机制,调用AMS启动新的Activity
2、 AMS会先回调Launcher(通过ActivityStack等跟activity栈有关的类)的ApplicationThread(Binder),然后走ActivityThread的pauseActivity相关的流程,最终调用到 Activity.performPause流程走pause生命周期
3、 走完pause后又回调到AMS的activityPaused方法,接着走ActivityStack的activityPausedLocked,然后是ActivityStackSupervisor,发现应用的进程还没有起来
4、 然后AMS发起创建应用进程的请求startProcess,走到zygote进程fork出新的应用进程,期间一通操作,最后会反射调用ActivityThread的main方法,在里面new一个ActivityThread,初始化Handler和Looper等
5、 在ActivityThread 的main方法里会调用attach方法,在里面会利用Binder通信,调用AMS的attachApplication
6、AMS后面又会调回到ActivityThread的handleBindApplication方法,这里主要是创建LoadedApk和ContextImpl,然后反射创建Instrumentation,接着调用LoadedApk的makeApplication方法,先初始化ClassLoader,然后创建ContextImpl,里面实际上是用 Instrumentation.newApplication方法通过类加载的方式加载的Application,加载完就立刻调用了Application的attach方法
7、 这里创建的ContextImpl没有赋值类加载器,包含的是线程信息和包的信息以及资源
8、这个加载application的类加载器就是前面创建的PathClassLoader,但实际上应该是通过双亲委托,用BootClassLoader加载的
9、 application的attach方法会调用attachBaseContext方法,给ContextWrapper的mBase赋值。也就是Application的attachBaseContext方法是最先调用的,比下面的Provider和Application的onCreate方法还早
10、 接着通过installContentProviders加载ContentProviders(这里可以看到ContentProvider是比Application的OnCreate方法更靠前的)
11、 接着通过 Instrumentation.callApplicationOnCreate方法,调用到Application的OnCreate方法
12、以上都走完,又会回到ActivityStackSupervisor,执行realStartActivityLocked进行Activity的加载

App里启动新的activity

同上面的不同,这种情况不会创建应用进程,也不会有Application的创建,这里是直接走activity的加载

创建初始化ClassLoader

1、 在上面的LoadedApk的makeApplication方法中,会先初始化ClassLoader
2、 这里通过LoadedApk的getClassLoader方法获取,如果ClassLoader为null,就调用createOrUpdateClassLoaderLocked方法
3、 这里刚刚创建LoadedApk,会调用ClassLoader.getSystemClassLoader()创建,并保存在mDefaultClassLoader
4、 上述方法最终会调用到ClassLoader.createSystemClassLoader()方法,这里会new一个PathClassLoader,并且Parent为BootClassLoader
5、 创建完成后,又赋值给LoadedApk的mClassLoader变量

LoadAPK
  • 里面有Resources这个成员,可以通过getResources方法获取

  • Resources里的AssetManager管理着APK中所有的资源,资源是通过native流加载

activity的启动加载过程

1、 AMS的ActivityStarter会创建ActivityRecord,然后会找出所有的适合Intent的Activity,如果有多个就会弹出dialog让用户选(最终是从PMS里找)
2、 根据启动标志位和Activity启动模式来决定如何启动一个Activity以及是否要调用deliverNewIntent方法通知Activity有一个Intent试图重新启动它,然后ActivityStackSupervisor一通调用,最后会回调到ActivityThread的handleLaunchActivity,主要逻辑是在performLaunchActivity方法
3、 通过Instrumentation用类加载加载Activity,然后调用activity的attach方法把activity、window、context进行绑定
4、 activity的attach方法里面,会创建PhoneWindow(会同时通过LayoutInflater的from方法创建LayoutInflater),以及其他一系列activity属性成员的初始化
5、 最后调用Instrumentation的callActivityOnCreate方法,调用activity的onCreate
6、 在activity的onCreate中,我们一般会setContentView,会调用到PhoneWindow的setContentView进行布局的加载,当然PhoneWindow会先进行decorView的加载,接着会就会调用LayoutInflater进行加载,最终通过createViewFromTag方法进行View的创建
7、 创建View时,是用的LayoutInflater中的一个Factory2的onCreateView接口

补充

activity启动流程AMS部分

1、 resolveActivity,找出最合适的activity,以及是否有result回调的处理
2、 一系列的权限校验
3、创建ActivityRecord对象
4、 调用startActivityUnchecked方法,这里面会进行启动模式的处理判断,

  • 主要是把处理结果在mLaunchFlags上追加对应的标记
  • 获取activity的启动栈,然后把mLaunchFlags设置给intent
  • 如果是clear_top模式,会清理栈上面的activity,然后会判断要不要去deliverNewIntent,去触发onNewIntent
  • 然后判断是否需要新创建一个task
  • 然后会走resumeTopActivityUnCheckedLocked方法

5、 resumeTopActivityInnerLocked方法里面会把之前的activity pause
6、 最后会调用到ActivityStackSupervisor的startSpecificActivityLocked方法,这里会判断当前应用进程是否已经启动,没有的话会先走启动App进程的流程,已经启动的话就走启动activity的流程(realStartActivityLocked)


欢迎关注我的公众号AntDream查看更多精彩文章!

目录
相关文章
|
12天前
|
缓存 前端开发 中间件
[go 面试] 前端请求到后端API的中间件流程解析
[go 面试] 前端请求到后端API的中间件流程解析
|
19天前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android 消息处理机制估计都被写烂了,但是依然还是要写一下,因为Android应用程序是通过消息来驱动的,Android某种意义上也可以说成是一个以消息驱动的系统,UI、事件、生命周期都和消息处理机制息息相关,并且消息处理机制在整个Android知识体系中也是尤其重要,在太多的源码分析的文章讲得比较繁琐,很多人对整个消息处理机制依然是懵懵懂懂,这篇文章通过一些问答的模式结合Android主线程(UI线程)的工作原理来讲解,源码注释很全,还有结合流程图,如果你对Android 消息处理机制还不是很理解,我相信只要你静下心来耐心的看,肯定会有不少的收获的。
59 3
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
11天前
|
安全 Java 编译器
Java 基础语法-面试题(53道)(基础概念+基础语法+流程控制)
Java 基础语法-面试题(53道)(基础概念+基础语法+流程控制)
37 18
|
18天前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
21天前
|
Java 编译器 程序员
JVM常见面试题(一):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别
JVM常见面试题(一):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别
JVM常见面试题(一):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别
|
7天前
|
开发工具 Android开发
解决Manifest merger failed : android:exported needs to be explicitly specified for <activity>
解决Manifest merger failed : android:exported needs to be explicitly specified for <activity>
17 1
|
19天前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
在Android开发中,事件分发机制是一块Android比较重要的知识体系,了解并熟悉整套的分发机制有助于更好的分析各种点击滑动失效问题,更好去扩展控件的事件功能和开发自定义控件,同时事件分发机制也是Android面试必问考点之一,如果你能把下面的一些事件分发图当场画出来肯定加分不少。废话不多说,总结一句:事件分发机制很重要。
63 9
|
24天前
|
XML Android开发 数据格式
Android 中如何设置activity的启动动画,让它像dialog一样从底部往上出来
在 Android 中实现 Activity 的对话框式过渡动画:从底部滑入与从顶部滑出。需定义两个 XML 动画文件 `activity_slide_in.xml` 和 `activity_slide_out.xml`,分别控制 Activity 的进入与退出动画。使用 `overridePendingTransition` 方法在启动 (`startActivity`) 或结束 (`finish`) Activity 时应用这些动画。为了使前 Activity 保持静止,可定义 `no_animation.xml` 并在启动新 Activity 时仅设置新 Activity 的进入动画。
35 12
|
19天前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
View的绘制和事件处理是两个重要的主题,上一篇《图解 Android事件分发机制》已经把事件的分发机制讲得比较详细了,这一篇是针对View的绘制,View的绘制如果你有所了解,基本分为measure、layout、draw 过程,其中比较难理解就是measure过程,所以本篇文章大幅笔地分析measure过程,相对讲得比较详细,文章也比较长,如果你对View的绘制还不是很懂,对measure过程掌握得不是很深刻,那么耐心点,看完这篇文章,相信你会有所收获的。
39 2
|
20天前
|
监控 Android开发 开发者
Android经典面试题之实战经验分享:如何简单实现App的前后台监听判断
本文介绍在Android中判断应用前后台状态的两种方法:`ActivityLifecycleCallbacks`和`ProcessLifecycleOwner`。前者提供精细控制,适用于需针对每个Activity处理的场景;后者简化前后台检测,适用于多数应用。两者各有优劣:`ActivityLifecycleCallbacks`更精确但复杂度高;`ProcessLifecycleOwner`更简便但可能在极端场景下略有差异。根据应用需求选择合适方法。
19 2