美文网首页Android开发Android技术知识Android开发
教你一种绕过谷歌禁止反射的方法

教你一种绕过谷歌禁止反射的方法

作者: Android_until | 来源:发表于2019-03-04 14:43 被阅读10次

Androi P之后Google可能会禁止使用反射来获取隐藏方法的调用,虽然在preview版本中只会以log的形式提示,但后续的版本可能会在使用反射时直接抛出错误。

这里提供其中一种破解反射禁止的方法,不过这种方法也有局限,就是只能用于本来已经是public或者static的隐藏方法。
对于这种类型的隐藏方法,我们之前的解决途径是通过反射来获取,因为虽然是public,但是方法被@hidden注解过,所以没法直接调用。
但虽然不能用反射,直接调用却是可以的。这就是具体的思路。

一、关于隐藏方法

我们知道在Android源码中有部分代码是不允许开发者使用的,这里要分两种情况。
· 没有打包进android.jar的类和方法,这部分不是隐藏的
· 打包进android.jar里的隐藏类和方法

如果查看源码,会发现有很多代码其实没有打进android.jar,比如internal包下的类,其中就有WindowManagerService。
这部分类之所以不打进android.jar,目的是这些类是只给android内部使用的,不希望开发者使用。

今天只说明对于没有打包进 android.jar的类,在不用反射的情况下的使用方法。

二、用provided的方式提供丢失的类

在gradle项目里,可以用provided的方式引入 java library,这样引入的library不会被打包进最终的apk里。
在gradle中这么写,

dependencies {
    provided project(':libhookandroid')
}

举个例子,比方这时候要用 ActivityThread,这里面有个 public方法 currentActivityThread(),我们要调用它,那么可以在lib项目下按报名建一个类

public class ActivityThread{
    public static ActivityThread currentActivityThread(){
        return null;
    }
}

为何可以return null呢?
因为它不会最终编译进apk,运行时调用的仍然是Android里的ActivityThread,那里有真正的实现逻辑,我们这里只是做了个壳用来保证编译时不会有问题。
写完lib后在主工程里就可以直接调用了,

    ActivityThread thread = ActivityThread.currentActivityThread();

因为是public方法,所以也不需要反射。

三、总结

对于Android里没有被打进 android.jar包中的类,可以通过 provided library的方式提供调用,
虽然P禁用了反射,但是直接调用是可以的。
然而缺点也是很明显,它不能用到 protected或者 private的方法。
对于其他的情况,我们可以通过修改apk的class loader改成 BootStrapClassLoader来实现绕过这个限制。
看过之前文章的朋友应该知道 BootStrapClassLoader是终极 ClassLoader,以后我们会介绍通过它来绕过限制的方法。

相关文章

网友评论

    本文标题:教你一种绕过谷歌禁止反射的方法

    本文链接:https://www.haomeiwen.com/subject/ndhiuqtx.html