FrameWork内核解析之XMS内核管理(一)上篇
阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680
本篇文章将继续从以下两个内容来介绍XMS内核管理之AMS:
- [Activity的管理]
- [ Android插件化开发之运行未安装apk的activity]
一、Activity的管理
1、ActivityRecord是Activity管理的最小单位,它对应着一个用户界面;
2、TaskRecord也是一个栈式管理结构,每一个TaskRecord都可能存在一个或多个ActivityRecord,栈顶的ActivityRecord表示当前可见的界面;
3、ActivityStack是一个栈式管理结构,每一个ActivityStack都可能存在一个或多个TaskRecord,栈顶的TaskRecord表示当前可见的任务;
4、ActivityStackSupervisor管理着多个ActivityStack,但当前只会有一个获取焦点(Focused)的ActivityStack;
5、ProcessRecord记录着属于一个进程的所有ActivityRecord,运行在不同TaskRecord中的ActivityRecord可能是属于同一个 ProcessRecord。
二、Android插件化开发之运行未安装apk的activity
2.1、介绍
我们知道PathClassLoader是一个应用的默认加载器(而且他只能加载data/app/xxx.apk的文件),但是我们加载插件一般使用DexClassLoader加载器,所以这里就有问题了,其实如果对于开始的时候,每个人都会认为很简单,很容易想到使用DexClassLoader来加载Activity获取到class对象,在使用Intent启动
2.2、替换LoadApk里面的mClassLoader
我们知道我们可以将我们使用的DexClassLoader加载器绑定到系统加载Activity的类加载器上就可以了,这个是我们的思路。也是最重要的突破点。下面我们就来通过源码看看如何找到加载Activity的类加载器。加载Activity的时候,有一个很重要的类:LoadedApk.Java,这个类是负责加载一个Apk程序的,我们可以看一下他的源码:
我们知道内部有个mClassLoader成员变量,我们只需要获取它就可以了,因为它不是静态的,所以我们需要先获取LoadApk这个类的对象,我们再去看看ActivityThread.java这个类。
我们可以发现ActivityThread里面有个静态的成员变量sCurrentActivityThread,然后还有一个ArrayMap存放Apk包名和LoadedApk映射关系的数据结构,我们通过反射来获取mClassLoader对象。
如果对ActivityThread.java这个类不熟悉的可以看我这篇博客,http://blog.csdn.net/u011068702/article/details/53207039 (Android插件化开发之AMS与应用程序(客户端ActivityThread、Instrumentation、Activity)通信模型分析)非常重要,是app程序的入口处。
2.3、实现具体代码
1)我们先需要一个测试apk,然后把这个测试的test.apk,放到手机sdcard里面去,关键代码如下
效果图如下:
接下来是我宿主代码:
MyApplication.java 这个类用实现替换mClassLoader
然后就是MainActivity.java文件,里面包含了下面另外一种方式,打开activity,所以我把函数 inject(DexClassLoader loader)先注释掉。
这里一定要注意,我们犯了3个错,
1、test.apk的路径写错了,下次写文件路径的时候,我们应该需要加上File file = new File(path); 用file.exist()函数来判断是否存在
2、从sdcard卡里面读取test.apk,没加上权限, <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3、写了Application,忘了在AndroidManifest.xml文件里面声明。
我们还需要注意要加上开启activity 在AndroidManifest.xml里面注册,切记,希望下次不要再次犯错。
AndroidManifest.xml文件如下:
运行结果如下:
然后这里又出现了插件资源和宿主资源冲突问题,我们后面再来研究。
4、合并PathClassLoader和DexClassLoader中的dexElements数组
我们首先来看一下PathClassLoader和DexClassLoader类加载器的父类BaseDexClassloader的源码:
(这里需要注意的是PathClassLoader和DexClassLoader类的父加载器是BaseClassLoader,他们的父类是BaseDexClassLoader)
这里有一个DexPathList对象,在来看一下DexPathList.java源码:
Elements数组,我们看到这个变量他是专门存放加载的dex文件的路径的,系统默认的类加载器是PathClassLoader,本身一个程序加载之后会释放一个dex出来,这时候会将dex路径放到里面,当然DexClassLoader也是一样的,那么我们会想到,我们是否可以将DexClassLoader中的dexElements和PathClassLoader中的dexElements进行合并,然后在设置给PathClassLoader中呢?这也是一个思路。我们来看代码:
然后运行的时候把MyApplication.java文件里面的函数loadApkClassLoader(mClassLoader);注释掉,然后把MainActivity.java文件里面的inject(MyApplication.mClassLoader)不要注释,运行效果一样。
阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680
参考https://blog.csdn.net/u011068702/article/details/53523609
https://www.jianshu.com/p/0bbcffbc7796
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· Ai满嘴顺口溜,想考研?浪费我几个小时
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密