【Android】Activity task和Instrumentation杂谈

news/2024/5/19 18:55:17/ 标签: android

文章目录

  • activity task
  • Instrumentation机制
  • 参考

Android不仅可以装载众多的系统组件,还可以将它们跨进程组成ActivityTask,这个特性使得每个应用都不是孤立的。

activity task

从数据结构角度看,Task有先后之分,源码实现上采取了stack的方式。这种方式不仅符合用户的逻辑思维和使用习惯,还可以极大复用了系统的资源。

在这里插入图片描述
如图,contacts和SMS分属两个进程,当我们在联系人详情activity中调起了短信进程的短信编辑activity,那么这两个activity就被放到同一个task里面了。这是栈管理activity的方式。

但是ActivityTask不能算严格意义的Stack,默认情况和栈是一致的,但是Android提供了更多的操作方式。

affinity即喜好的意思,它代表这个activity希望归属的task,默认情况同一个程序有共同的affinity,<AndroidManifest.xml>中声明的Package Name。我们也可以主动在中使用taskAffinity标签属性来指定整个应用程序的Affinity。

一个activity task的affinity取决于它的根activity

在默认情况下,目标Activity将与startActivity的调用者处于同一Task中。但如果用户特别指定了FLAG_ACTIVITY_NEW_TASK,表明它希望为Activity重新开设一个Task。

这时就有两种情况:假如当前已经有一个Task,它的affinity与新Activity是一样的,那么系统会直接用此Task来完成操作,而不是另外创建一个Task;否则系统需要重启一个Task。

如果Activity指定了allowTaskReparenting,且后期程序的Task转为前台,它会被移动到和它更“亲近”的task中。

还有一种就是我们常见到的android:launchMode了,比较基础,这里就不展开了。

还有Intent的flag,具体可以查看源码或者官方文档。

Instrumentation机制

Base class for implementing application instrumentation code. When running with instrumentation turned on, this class will be instantiated for you before any of the application code, allowing you to monitor all of the interaction the system has with the application. An Instrumentation implementation is described to the system through an AndroidManifest.xml’s tag.
https://developer.android.com/reference/android/app/Instrumentation

Android系统在/system/bin下提供了很多“中介”程序让用户间接使用system server,例如pm、am等。

Instrumentation是ActivityManager的核心功能之一。

这是官方给出的Instrumentation的adb使用方法:
在这里插入图片描述

"-e"用于指定额外参数,这里给个使用例子:

adb shell am instrument -e class com.lxs.instrument.TestCase -w com.lxs.instrument /android.test.InstrumentationTestRunner

下面分析下它的执行"-e"和 [component]处理流程。

"am instrument"命令由runInstrument的am.java负责解析,和 [component]相关的代码如下:

		//cnArg 就是Component字符串String cnArg = nextArgRequired();//unflatten规则就是以“/”为分隔符,前部分是package,剩余是Class。ComponentName cn = ComponentName.unflattenFromString(cnArg);

“-e”后面所有的[name value]被保存到一个Bundle对象中,和其它参数一起传给AMS,AMS在承载它的进程进行关联后,由BindApplication的ActivityThread处理:

/*frameworks/base/core/java/android/app/ActivityThread.java*/private void handleBindApplication(AppBindData data) {if (data.instrumentationName != null) {//instrumentationName是一个ComponentName对象InstrumentationInfo ii = null;try {ii = appContext.getPackageManager().getInstrumentationInfo(data.instrumentationName, 0);} catch (PackageManager.NameNotFoundException e) {}…mInstrumentationPackageName = ii.packageName;LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,appContext.getClassLoader(), false, true, false);ContextImpl instrContext = ContextImpl.createAppContext(this, pi);try {java.lang.ClassLoader cl = instrContext.getClassLoader();mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();} catch (Exception e) {}mInstrumentation.init(this, instrContext, appContext,new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,data.instrumentationUiAutomationConnection);} else {mInstrumentation = new Instrumentation();}try {Application app = data.info.makeApplication(data.restrictedBackupMode, null);mInitialApplication = app;try {mInstrumentation.onCreate(data.instrumentationArgs);}catch (Exception e) {}try {mInstrumentation.callApplicationOnCreate(app);} catch (Exception e) {}} finally {StrictMode.setThreadPolicy(savedPolicy);}}

AppBindData保存了和应用启动相关的所有关键数据。data.instrumentationArgs对应的是“am instrument”命令中“-e”所指定的额外参数;而data.instrumentationName对应的是“am instrument”命令中的 < COMPONENT >,我们可以根据这个参数构造出用户指定的Instrumentation对象(例如android.test.InstrumentationTestRunner)。当然,如果应用程序并没有Instrumentation组件,那么系统会使用默认的Instrumentation类。

由handleBindApplication的处理可以知道,一个Instrumentation对象的生命周期包括但不限于:

newInstance-> init-> onCreate->onStart-> callApplicationOnCreate->callActivityOnCreate
->callActivityXXX->onDestroy->

Instrumentation提供了一种允许用户获取/改变应用和系统之间的交互流程的机制,自动化测试框架只是其中一种应用形式。InstrumentationTestRunner的原理框架如图:
在这里插入图片描述

如果用户没有指定Instrumentation的话,它的很多行为是“伪实现”,来看下:

/*frameworks/base/core/java/android/app/Instrumentation.java*/public void onCreate(Bundle arguments) {//空实现
}
    public void callActivityOnPause(Activity activity) {activity.performPause();//默认情况下,将直接调用Activity元素的onPause
}

它们之间的关系:
在这里插入图片描述
Instrumentation和ActivityThread运行于同一进程之中,那么它们是否还处于同一个线程呢?
默认情况是肯定的,但是Instrumentation提供了一个方法:

/*frameworks/base/core/java/android/app/Instrumentation.java*/
public void start() {if (mRunner != null) {throw new RuntimeException("Instrumentation already started");}mRunner = new InstrumentationThread("Instr: " + getClass().getName());mRunner.start();}

通过这个方法,会运行在新开的一个线程中。

参考

《深入理解Android内核设计思想》


http://www.ppmy.cn/news/1424479.html

相关文章

redisson -- 延迟队列RDelayedQueue

1.maven配置 <!-- 用于管理起步工程的依赖管理 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.11</version><relativePath/> </parent…

【Linux】基础I/O>文件系统软硬链接动静态库详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;Linux_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.C语言文件接口 1.1 hello.c写文件 1.2 hello.c读文件 1.3 输出信息到显示器 1.4 stdin & stdout & stderr 1.5 总结打…

华为OD-C卷-路口最短时间问题[200分]Java 100%

题目描述 假定街道是棋盘型的,每格距离相等,车辆通过每格街道需要时间均为 timePerRoad; 街道的街口(交叉点)有交通灯,灯的周期 T(=lights[row][col])各不相同; 车辆可直行、左转和右转,其中直行和左转需要等相应 T 时间的交通灯才可通行,右转无需等待。 现给出…

如何使用OSI七层模型的思路进行Linux网络问题排障?

在运维工作中&#xff0c;我们可能经常遇到诸如服务器无法远程连接、网站无法访问等各种网络问题。此时你是否想过&#xff0c;我们常背的OSI七层模型&#xff0c;能在处理这样的实际问题中发挥什么样的作用呢&#xff1f; 基于OSI架构的方法论&#xff0c;我们可以使用自下而…

关于系统数据缓存的思考以及设计

文章目录 引言案例A项目B项目 分析我的实现总结 引言 缓存&#xff0c;这是一个经久不衰的话题&#xff0c;它通过“空间换时间”的战术不仅能够极大提升处理查询性能还能很好的保护底层资源。最近针对系统数据缓存的优化后&#xff0c;由于这是一个通用的场景并且有了一点心得…

再拓信创版图-Smartbi 与东方国信数据库完成兼容适配认证

近日&#xff0c;思迈特商业智能与数据分析软件 [简称&#xff1a;Smartbi Insight] V11与北京东方国信科技股份有限公司 &#xff08;以下简称东方国信&#xff09;CirroData-OLAP分布式数据库V2.14.1完成兼容性测试。经双方严格测试&#xff0c;两款产品能够达到通用兼容性要…

计算机网络(王道考研)笔记个人整理——第二章

第二章 物理层主要任务&#xff1a;确定与传输媒体有关的一些特性 机械特性&#xff1a;物理连接的特性 规定物理连接时所采用的规格、接口形状、引线数目、引脚数量和排列情况 电气特性 规定传输二进制位时&#xff0c;线路上信号的电压范围、阻抗匹配、传输速率和距离限制等…

VectorMap论文阅读

1. 摘要 自动驾驶系统需要对周围环境具有很好的理解&#xff0c;包括动态物体和静态高精度语义地图。现有方法通过离线手动标注来解决语义构图问题&#xff0c;这些方法存在严重的可扩展性问题。最近的基于学习的方法产生稠密的分割预测结果&#xff0c;这些预测不包含单个地图…

Oracle——领先的企业级数据库解决方案

一、WHAT IS ORACLWE&#xff1a; ORACLE 数据库系统是美国 ORACLE 公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器(CLIENT/SERVER)或B/S 体系结构的数据库之一&#xff0c;ORACLE 通常应用于大型系统的数…

Leetcode - 周赛393

目录 一&#xff0c;3114. 替换字符可以得到的最晚时间 二&#xff0c;3115. 素数的最大距离 三&#xff0c;3116. 单面值组合的第 K 小金额 四&#xff0c; 3117. 划分数组得到最小的值之和 一&#xff0c;3114. 替换字符可以得到的最晚时间 本题是一道模拟题&#xff0c;…

51单片机串口输出问题(第一个字符重复,自动循环输出第一个字符)

遇到的问题描述 51单片机使用串口发送数据时出现只循环发送字符串的第一个字符的情况。就算发送的是第一个字符也有时候一直发送。 串口函数代码 参考串口发送注意 #include <reg52.h> //此文件中定义了单片机的一些特殊功能寄存器void UsartInit() {SCON0X50; /…

Windows上构建 Chisel-Bootcamp

windows环境构建本地Chisel-Bootcamp 安装摘要Chisel-boocamp环境搭建安装java安装Anaconda安装scala 下载Chisel-bootcamp 环境Reference 安装摘要 在windows上安装chisel-boocamp&#xff0c;与linux过程类似。 安装java8安装anaconda安装scala下载Chisel-bootcamp环境 Ch…

并发场景下 缓存击穿 穿透 雪崩如何解决

最近建了一个技术交流群&#xff0c;欢迎志同道合的同学加入&#xff0c;群里主要讨论&#xff1a;分享业务解决方案、深度分析面试题并解答工作中遇到的问题&#xff0c;同时也能为我提供写作的素材。 群号 208236931&#xff0c;欢迎进群交流学习&#xff0c;一起进步、进步、…

泛型的初步认识(1)

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x…

【Linux】地址空间虚拟地址

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 虚拟地址1.1 虚拟地址引入1.2 虚拟地址理解1.3 虚拟地址细节问题 2. 地址空间2.1 理解地址空间2.2 页表和写时拷贝 3. 进程调度 1. 虚拟地址 1.1 虚拟地址引入 先先来一个测试代码&#xff1a; 1 #include<st…

深入探讨虚拟现实中的新型安全威胁:“盗梦攻击”及其防御策略

随着虚拟现实&#xff08;VR&#xff09;技术的飞速发展&#xff0c;用户体验达到了前所未有的沉浸水平&#xff0c;但也暴露在一系列新的安全威胁之下。本文着重介绍了近期出现的一种高度隐秘且影响深远的攻击手段——“盗梦攻击”。这一概念由芝加哥大学的研究人员提出&#…

【每日刷题】Day7

【每日刷题】Day7 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 2. 203. 移除链表元素 - 力扣&#xff08;…

C++反向迭代器的封装和模板进阶(个人笔记)

C反迭代器和模板进阶 1.反向迭代器2.模板2.1非类型模板参数2.2模板的特化2.2.1函数模板2.2.2类模板特化2.2.2.1 全特化2.2.2.1 偏特化 2.3模板的分离编译2.4模板的优缺点 1.反向迭代器 用正向迭代器适配出反向迭代器 这里是自己实现的反向迭代器版本&#xff0c;与STL标准库里…

监督算法建模前数据质量检查

一、定义缺失值检测函数 def missing_values_table(df):# 总的缺失值mis_val df.isnull().sum()# 缺失值占比mis_val_percent 100 * df.isnull().sum() / len(df)# 将上述值合并成表mis_val_table pd.concat([mis_val, mis_val_percent], axis1)# 重命名列名mis_val_table_…

数据结构—顺序表实现通讯录

在上一节我们基本了解了顺序表的基本知识&#xff0c;接下来我们就用顺序表来实现一下通讯录。 一、基于动态顺序表实现通讯录 1.1 功能介绍 1. 能够保存用户信息&#xff1a;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;电话&#xff0c;地址等 2. 添加联系人信息 3. …