Android 9.0源码解读系列(一)Activity启动流程

Android 面试总结 - Activity的启动流程(2) 光有这些思路和搞懂单个知识的应用是还远远不够的,在Android开源框架设计思想中的知识点还是比较多的,想要搞懂还得学会整理和规划:我们常见的**Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、IOC依赖注入框架、最近架构组件Jetpack等等Android第三方开源框架,**这些都是属于Android开源框架设计思想的。如下图所示:这位阿里P8大佬针对以上知识点,熬夜整理出了一本长达1042页的完整版如何解读开源框架设计思想。 阅读详情

从今天开始,我将带领大家一起来解读Android 9.0的源码。在最近这几年,笔者的工作都是和framework的修改相关,对于这一块比较熟悉。因此,我力求能用最通俗易懂的语言,让刚开始接触源码的同学也能有所收获。为了描述方便,文中我们统一用AMS表示ActivityManagerService。废话不多说,我们直接进入正题。

在入门Android开发时,我们就已经知道如何去启动一个新的Activity了。我们以显式Intent为例,一般代码如下:

    Intent intent = new Intent(this,ActivityXXX.class);
    startActivity(intent);

或者

    Intent intent = new Intent(this,ActivityXXX.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);

第一种方式,一般我们是在Activity中这样使用;对于第二种方式,我们主要是在一些非界面的情况下使用,如BroadcastReceiver、Service等。现在我就分别来介绍这两种方式的启动流程是怎样的。

一、startActivity

(1)使用Activity启动

我们首先来看Activity.java中,关于startActivity是怎么定义的。

public class Activity extends ContextThemeWrapper implements ...{

    ...
	
    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
	
    @Override
    public void startActivity(Intent intent, Bundle options) {

        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {

            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.

            //默认不加 options时,会走这个分支
            startActivityForResult(intent, -1);
        }
    }

    public void startActivityForResult(Intent intent, int requestCode){
        startActivityForResult(intent, requestCode, null);
    }
	
    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
	...

	//启动目标Activity
	Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this,
            mMainThread.getApplicationThread(), mToken, this, 
            intent, requestCode, options);

	//发送执行结果		
	if (ar != null) {
            mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode,
                ar.getResultCode(), ar.getResultData());
	}
	...
	
	//取消当前Activity的输入事件,并开始过渡退出
	cancelInputsAndStartExitTransition(options);
	...
    }

    ...

}

从上面代码我们可以总结出,在startActivityForResult方法中,主要做了3件事情:

1、调用 Instrumentation.execStartActivity方法来启动Activity,并返回执行结果;

2、如果执行结果不为空,则通过ActivityThread. sendActivityResult方法,将执行结果返回到 Activity(或Fragment) 中;

这里的mMainThread是ActivityThread对象。在ActivityThread中,则会通过ClientTransaction、ActivityResultItem等类的中转,调用Activity的dispatchActivityResult方法, 并最终调用我们所熟悉的onActivityResult方法。关于ClientTransaction等,我们本文后续会再提到并详解;

3、取消当前Activity的输入事件,包括TouchEvent、KeyEvent 等,并开始退出。

 

(2)使用Context启动

我们都知道,在Android中,Context是一个抽象类,而其具体的实现类是ContextImpl。而至于Context其他相关类,如ContextWrapper,都是对ContextImpl的一种装饰(功能的增强),这是设计模式中典型的装饰模式。如果我们不了解装饰模式也没关系,目前知道Context的实现类是ContextImpl就行了。

我们来看ContextImpl中关于startActivity是如何定义的

public class ContextImpl extends Context {
    ...
	
    @Override
    public void startActivity(Intent intent) {
        //如果是系统进程调用此方法,则打印 Log警告应使用startActivityAsUser
        warnIfCallingFromSystemProcess();
		
        //启动Activity
        startActivity(intent, null);
    }
	
    @Override
    public void startActivity(Intent intent, Bundle options) {

        //判断是否加入FLAG_ACTIVITY_NEW_TASK标志
        final 
Android多用户适配 本文基于Android Q,介绍安卓原生的多用户功能适配相关内容,供开发者学习参考。 阅读详情

相关推荐

Android应用程序启动(根Activity)过程

注释1:从 ServiceManager得到一个IBinder,也就是 “IBinder类型的AMS”注释2:将IBinder通过转换成一个 IActivityManager对象,通过get()可以得到这个对象。上面是AIDL的做法,用 进程间通信完成的从 客户端层到 服务端层的实现。8.0之前并不是AIDL的做法。至于AIDL的用法、原理网上已经有n多的blog去学习了。这里不再赘述。至此,第一阶段结束,方法最终会调用到。这部分其实特别好理解。

2401_83641098的博客 1227

Android M Launcher3主流程源码浅析

当存在多个时无论哪种触发都会弹出选择框进行选择设置。可以发现,Launcher3的Activity加载其实和其他应用没啥区别的,也是一样的流程,只是我们需要特别注意上图中红色的两步。在setContentView之后我们其实又进行了一次依据设备属性的layout操作,接着才进行异步数据加载的,所以我们的重点会放在LauncherModel的loader方法中。可以发现,其实Launcher没啥特殊的,只是考虑的问题比较多而已,本文只是给出主流程,细节还需自己继续扣,略显潦草,没办法,没时间,只能这样。

2401_89173673的博客 747

Android5.0 Activty启动流程源码分析

看了标题很多人可能会说Android10都出来了,为什么你还要写一篇Android5.0中Activity的启动流程,我们知道Android 5.0是Google于2014 年 10 月分发布的,而上上个月也就是9分月Android10正式发布了,这样一看确实有些不合适,其实我本来是要写Android10的,但是为了知识的完整性以及Android5.0和Android10之间有一个明显的对比,遵循...

门心叼龙的专栏 1466

Ubuntu技巧-Ubuntu远程访问之SSH反向代理

💡大家好,我是可夫小子,《小白玩转ChatGPT》专栏作者,关注AIGC、互联网和自媒体。要把内网的一台的Ubuntu服务器让外面也能访问,总共有三种可行的方案,前面已经介绍了两种方式,今天就来介绍更健壮稳定的方式——ssh反向代理。大概的框架图如下,今天就从服务器购买到设置,手把手的教程,让你花费100块以内,就拥有一个强大的「云服务器」。

可夫小子的频道 1151

深入了解神经网络:构建人工智能的基石

这篇博客将为您解释神经网络的构造,让您能够理解这个令人着迷的领域的基本工作原理。神经网络是人工智能领域的关键技术,它们的构造基于神经元的灵感,并结合了数学、统计和机器学习的原理。输入可以类比为神经元的树突,而输出可以类比为神经元的轴突,计算则可以类比为细胞核。较好的方法就是预先设定几个可选值,通过切换这几个值来看整个模型的预测效果,选择效果最好的值作为最终选择。:这是神经网络的核心部分,包含多个层次的神经元。、神经网络结构图中的拓扑与箭头代表着预测过程时数据的流向,跟训练时的数据流有一定的区别;

AI_dataloads的博客 2万+

机器学习第四个算法ANN(人工神经网络)

我是在14年9月刚读研的时候听到一个说法叫“类人脑算法”很火热,之后搞了很长一段时间相关的蓄水池算法等,但大都没有摸到门路而中途放弃了。现今看来,还是缺少一些知识背景,也不善于在网络上学习,随时间推移,也逐渐明白这是机器学习的一小部分,并且逐渐发展的名称叫做人工神经网络的算法,如果网络层较多,又会有个别名,叫做深度学习。其中个用到的最著名的算法是背向传输算法(backpropagation),而这个

legalhighhigh的博客 1万+

C++游戏开发实战:从零构建局域网联机对战系统(附完整代码解析)

本文详细介绍了如何使用C++开发局域网联机对战游戏系统,涵盖从环境搭建到实战代码解析的全过程。重点讲解了Winsock库的应用、Socket通信原理、服务端与客户端开发技巧,以及性能优化和安全防护方案,帮助开发者快速掌握C++游戏开发的核心技术。

weixin_42524945的博客 444

AMESim柱塞泵建模全指南:从HCD库搭建到联合仿真

液压系统仿真中,轴向柱塞泵的建模始终是难点与热点。柱塞泵结构紧凑、功率密度高,在工程机械与航空航天领域应用广泛,然而其运动学与流体细节深度耦合,给仿真带来不小挑战。AMESim平台中的HCD库提供了一种从物理结构出发的建模思路,将柱塞泵分解为容积腔、节流口与机械约束等基础单元,从而真实刻画柱塞腔压力波动、配流特性和容积效率等关键行为,摆脱黑盒模型的局限。基于机理建模的仿真结果,可用于泵参数优化、故障特征分析以及控制策略验证。进一步结合AMESim与Simulink联合仿真,可以高效开发变量泵排量控制系统,研

weixin_29159441的博客 288

别再只会用串口助手了!手把手教你用手机App调试HC-05蓝牙模块(STM32F103实战)

本文详细介绍了如何利用手机App调试HC-05蓝牙模块与STM32F103的无线连接,突破传统串口助手的限制。通过实战指南,开发者可以掌握移动性测试、实时监控和快速验证等高效调试技巧,优化蓝牙透传的稳定性和性能。

weixin_33670786的博客 428

用PyTorch手把手搭建液态神经网络(LNN):从微分方程到无人机避障实战

本文详细介绍了如何使用PyTorch搭建液态神经网络(LNN),从微分方程基础到无人机避障实战应用。LNN通过动态时序建模和微分方程实现高效计算,特别适合多传感器数据融合场景。文章包含完整的代码实现、训练技巧及性能优化方案,帮助开发者快速掌握这一前沿技术。

uber9的博客 438

VS2019编译配置Easy3D

VS2019编译配置Easy3D

dayuhaitang1的博客 2596

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: ListView中如何使用Button,让onClick和onItemClick事件共存
冒泡彩虹
博客等级 码龄14年 17粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值