【Android】Activity task和Instrumentation杂谈

2024-04-17 01:04

本文主要是介绍【Android】Activity task和Instrumentation杂谈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 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内核设计思想》

这篇关于【Android】Activity task和Instrumentation杂谈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/910393

相关文章

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤