讨论 Xposed 模块的类和宿主中的类

讨论 Xposed 模块的类和宿主中的类

前言

Xposed 模块是一种Android应用程序的插件,可以为手机增加各种功能和特性,而无需修改操作系统或应用程序的源代码。这使得用户可以更轻松地个性化和改进Android设备。

所以,Xposed 框架其实就是一种组件化开发的技术。

基本前提

在讨论前,我们要了解几个基本前提:

  1. 类对象在同一个Classloader中具有唯一性,具有唯一类名
  2. 类对象相等的前提
    • 类名相同
    • 加载类对象的Classloader相同
  3. Classloader实例存在父子关系,且具有双亲委托机制,可以理解为子Classloader拥有父Classloader的全部类对象,因此如果父亲已经存在某类名,无法再次加载改类
  4. 插件中的Classloader和宿主中的Classloader不是同一个
  5. 在插件的代码中的所有能直接引用的类都由模块Classloader加载

普通插件和宿主相互调用的解决方法

有了基本前提我们可以了解一下一些常见的普通插件和宿主相互调用的解决方法,其实就是解决两个问题:

  1. 插件如何加载宿主中的类。
  2. 宿主如何加载插件中的类。

参考博客

第一个问题比较简单,我们只需要在构造插件DexClassLoader时,把宿主PathClassLoader作为parent传递进去(双亲委托模型)。

第二个问题比较复杂,因为宿主PathClassLoade没办法直接拿到插件的信息。那有没有办法在运行期间动态向宿主PathClassLoader添加插件apk信息呢?答案是肯定的,它要靠上文提到的dexElements完成。我们在原理部分分析了宿主PathClassLoader加载类的动作实际上是遍历DexPathListdexElements完成的,如果我们将插件DexClassLoader中的dexElements添加到宿主PathClassLoader中去,是不是宿主PathClassLoader也有了插件的信息了呢。

只要解决这两个问题,在代码层面上,当宿主希望调用插件的对象时,可以在引入一个Stub包(即compileOnly),然后在加载插件中的类后,即可使用。

同理,插件可以直接使用宿主的方法,因为插件的Classloader父亲必是宿主的Classloader

但是,这种解决方法在 Xposed 模块中并不能使用,因为 Xposed 模块在大多数情况下都是由系统Classloader进行加载,即无法拿到宿主中的类(除非宿主是android)。因此初学者想要通过在模块下写一个Stub类就想调用宿主的方法,得到只会是ClassNotFoundException异常。

Xposed 中的类加载原理

Xposed 模块和其他应用组件模块不同,Xposed 模块大多情况下由系统的Classloader进行加载。结构图如下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

截图来源,也可以看看他更详细的博客

所以我们可以知道,Xpsoed 模块中的Classloader只加载系统的jar包,对应App中独有的类对象,Xposed 模块是不被加载的。所以如果想调用宿主实例的方法只能通过反射进行

我觉得如果优化一下Xposed框架或许真能达到这种效果

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值