学习笔记:插件化Activity

简介: 学习笔记:插件化Activity

四大组件之Activity:

名词解释

AMS:AMS Binder对象

AMN:app中获取AMS代理的对象

ATP:ApplicationThreadProxy用于AMS和APP通信,AT的代理对象

APT:ApplicationThread APP中的Binder对象。APT中会利用mh这个Handler发送消息做对应处理

AT:APT会调用AT得方法,AT中给mh发消息

mh:App的Handler,用于接受处理AMS等系统服务发送的消息处理

原始流程

startActivity交互过程如下:

App:

ContextTheme—>ContextWrapper—>Context—>ContextImpl:

ContextImpl内部调用Instrumention.startActivity()传入启动Activity的类名(用于校验是否注册过没有注册抛异常)等信息,该方法其中通过AMN获取AMS代理对象和AMS进行通信。

AMS远端:

获取要启动的activity类名,观察是否在清单文件中注册过(PMS在安装时会解析对应APK清单文件存储到本地)。接着给启动activity的进程发送一个pause的消息通过ATP

然后判断该进程是否启动过(没有启动需要先和zygote用socket通信先创建一个进程Process.start)

1.没有启动过(没有启动需要先和zygote用socket通信先创建一个进程Process.start,接着创建ActivityThread,利用AMN把ATP传给AMS(这样AMS就可以和APP通信了)

接着AMS在给ATP发消息 AT收到给mh发送消进行反射创建Application调用onCreate,在接着就是下面2中所说的进程已经启动情况的步骤了)

2.启动过(AMS会封装Activity变成一个ActivityClientRecord,该对象会携带cl后面mh会根据这个cl去反射创建Activity。)

APP中:

ATP中收到AMS发过来的消息取出ActivityClientRecord,调用AT吧这个参数传进去。

AT中调用mh的handlerPerformLaunchActivity。mh其实是一个handler,handleCallBack中来决定调用哪个方法对应于本示例startActivity为下面的逻辑

回调中取出acRecord,利用acRecord的classloader对象来反射创建对应activity,并调用onCreate方法

通知最开始pause的那个activity恢复运行~(利用ATP也是)

至此交互结束

Hook点

我们可以Hook哪些点呢?提炼出精华我们在哪里可以把狸猫换成太子~

第一个点:

Instrumention利用AMN获取到AMS代理,将信息传给AMS校验

(我们在Instrumention中拦截这个代理,替换为我们自定义的对象。检测到startActivity时将Activity换成我们宿主中已经注册了的StubActivity)

好了,现在AMS校验过了,他要通知APP创建Activity对象了。但是这个时候是StubService的Activity。我们需要把他换掉我们真实启动的Activity。

第二个点:

我们怎么知道真实启动的Activity是谁呢?在第一步中其实整个流程传递的都是Intent,包括我们接受到ANS消息时也是Intent。

既然是同一个Intent对象。我们在这个Intent中动手脚(APP调用AMS把真实启动的Activity保存到Intent中,在AMS通知APP创建的时候在取出来)

好,第一个是在Instrumention中换成我们的代理接下来就会和AMS交互(这里是最后一步下一步就要和AMS通信因此选在这里进行Hook)

那么通知ATP,AT,mh中都可以进行还原取出Intent中真实启动的activity。

我们在mh中最后一步反射创建的地方进行修改(和上面一样,在最接近现场的地方进行Hook)。将mh替换为我们的mh。这样我们收到handlerPerformLaunchActivity的消息时,就可以做我们自己的操作了

不同的ClassLoader会加载不同的类,classloader中如果没有这个class是加载不了的。所以我们要用正确的cl去加载对象。这个cl其实就是插件的cl,也就是dexcl。我们在和AMS交互的时候可以传入对应的cl,之后创建再取出正确的cl。

注意点:

由于Activity默认是Standard模式,所以宿主中的一个Activity可以对应插件中的多个标准模式的Activity。每次启动都会创建一个实例。

但是Android中是有LaunchMode的,不同的启动模式对应的效果也不同。那么如何支持LaunchMode呢

LaunchMode的支持:

其实就是Activity栈的变化。我们自己手动保存一份当前启动的Activity信息集合,根据启动Activity的launchmode去操作这个集合并对集合中的Activity实例做处理【这个也是Android原生的处理方式】

(要保存两个集合一个是已经启动的集合commentName为key,真实的Activity实例为value(这个模拟的就是Activity栈);一个是当前APK中所有的Activity集合(是否可以通过类名找到对应的Activity信息)name对应ActivityComment)

注:第二个集合需要在Application的attachBaseContext中去完善这个集合。越早越好

流程:

1.先遍历第二个集合中看插件中是否有对应Activity的信息。很好理解如果你启动一个压根就不存在的Activity之后反射也会崩溃~~

这之后的代码逻辑就是mh中Hook那个handlerPerformLaunchActivity的消息时的处理,针对创建Activity实例和调用Activity方法进行额外的逻辑处理

2.首先看下已经启动的集合中Activity的数量,launchmode是针对多Activity才有用,如果栈中只有一个Activity那么launchmode将没用

3.再接着取出这个activity的launchmode是不是非Standard的,默认模式不需要处理,直接把他加到我们的第一个已经启动activity的集合中即可。原生也是这样

3.1

SingleTop:

首先看下原生的这个启动模式是什么样的情况:

如果栈顶是这个Activity那么将不会创建实例也不会调用onCreate,而是会调用他的onNewIntent方法。否则就是按Standard处理

我们怎么处理呢~~

注意:本质上我们还是standard的:

原先:S1–>T1 之后就是S1–>T1(有状态的)—>T1了,

Question:我们可以把之前Top的T1干掉吗也就是中间的那个T1,就是S1—>T1了~

A:不行,这样启动的T1状态会丢失。真实的情况应该仅仅是调用T1(有状态的)的onNewInstance

怎么做呢:不添加这个后来的activity,直接取出栈顶的activity实例调用OnNewInstance即可~~

对应逻辑:

先看下栈顶是不是这个activity。

~如果不是就直接加入到集合中就行,也就是默认Standard模式

~如果是的话,则忽略这个要启动的Activity,把栈顶的Activity取出来调用onNewInstance即可

3.2

SingleTask:

首先看下原生的这个启动模式是什么样的情况:

如果在栈中已经有该Activity实例了,那么清除掉在它上面的所有Activity,并调用这个Activity的onNewInstance方法

根据前面那个mode的处理,应该也能猜出怎么做了

在集合中找出这个Activity实例和他对应的下标。进行对这个范围(下标–集合最大数量)的activity实例进行挨个销毁。

接着在调用这个activity的onNewInstance方法

3.3:SingleInstance:

一样的操作。



相关文章
|
7天前
|
人工智能 运维 安全
|
5天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
B站开源IndexTTS2,用极致表现力颠覆听觉体验
在语音合成技术不断演进的背景下,早期版本的IndexTTS虽然在多场景应用中展现出良好的表现,但在情感表达的细腻度与时长控制的精准性方面仍存在提升空间。为了解决这些问题,并进一步推动零样本语音合成在实际场景中的落地能力,B站语音团队对模型架构与训练策略进行了深度优化,推出了全新一代语音合成模型——IndexTTS2 。
588 20
|
12天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
949 110
|
6天前
|
人工智能 测试技术 API
智能体(AI Agent)搭建全攻略:从概念到实践的终极指南
在人工智能浪潮中,智能体(AI Agent)正成为变革性技术。它们具备自主决策、环境感知、任务执行等能力,广泛应用于日常任务与商业流程。本文详解智能体概念、架构及七步搭建指南,助你打造专属智能体,迎接智能自动化新时代。