Android 反射调用 SDK 隐藏方法抛错 NoSuchMethodError
本文最后更新于 380 天前,其中的信息可能已经有所发展或是发生改变。
内容目录

参考文章:针对非 SDK 接口的限制 | Android 开发者 | Android Developers

最近在写 Android 系统应用的时候,因为某些特殊原因无法接触到 AOSP 开发环境,只能通过第三方应用 + 系统签名的方式调试。

其中一个功能是要通过 EthernetManager 获取到 configuration,于是乎首先用先前在 Android 8.0 上的经验,用反射的方式调用方法:

EthernetManager.getMethod("getConfiguration", String::class.java)
    .invoke(getSystemService("ethernet"), target) ?: IpConfiguration.newInstance()

但是这段代码抛错 NoSuchMethodError,直接列举所有方法也只有屈指可数的少数几个方法:

12:29:38.203 ReflectTest D  android.net.EthernetManager declaredMethods: enableEthernet(arg0: boolean): void
12:29:38.203 ReflectTest D  android.net.EthernetManager declaredMethods: getDns(arg0: java.lang.String): java.lang.String
12:29:38.203 ReflectTest D  android.net.EthernetManager declaredMethods: getGateway(arg0: java.lang.String): java.lang.String
12:29:38.203 ReflectTest D  android.net.EthernetManager declaredMethods: getIpAddress(arg0: java.lang.String): java.lang.String
12:29:38.203 ReflectTest D  android.net.EthernetManager declaredMethods: getNetmask(arg0: java.lang.String): java.lang.String
12:29:38.203 ReflectTest D  android.net.EthernetManager declaredMethods: getState(): int
12:29:38.204 ReflectTest D  android.net.EthernetManager declaredMethods: requestTetheredInterface(arg0: java.util.concurrent.Executor, arg1: android.net.EthernetManager.TetheredInterfaceCallback): android.net.EthernetManager.TetheredInterfaceRequest
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: enableEthernet(arg0: boolean): void
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: equals(arg0: java.lang.Object): boolean
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: getClass(): java.lang.Class
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: getDns(arg0: java.lang.String): java.lang.String
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: getGateway(arg0: java.lang.String): java.lang.String
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: getIpAddress(arg0: java.lang.String): java.lang.String
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: getNetmask(arg0: java.lang.String): java.lang.String
12:29:38.204 ReflectTest D  android.net.EthernetManager methods: getState(): int
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: hashCode(): int
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: notify(): void
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: notifyAll(): void
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: requestTetheredInterface(arg0: java.util.concurrent.Executor, arg1: android.net.EthernetManager.TetheredInterfaceCallback): android.net.EthernetManager.TetheredInterfaceRequest
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: toString(): java.lang.String
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: wait(): void
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: wait(arg0: long): void
12:29:38.205 ReflectTest D  android.net.EthernetManager methods: wait(arg0: long, arg1: int): void

代码跑在 Android 12 上,于是乎考虑是否是新增了什么特性限制了反射。查阅文档,发现是在 Android 9 开始新增了 针对非 SDK 接口的限制,我遇到的情况正好符合 访问受限的非 SDK 接口时可能会出现的预期行为

仔细查阅日志确实有这么一段:

14:01:42.489 ttingspppoetes                  W  Accessing hidden method Landroid/net/EthernetManager;->getConfiguration(Ljava/lang/String;)Landroid/net/IpConfiguration; (max-target-r, reflection, denied)

由于我这里的目的仅仅是本地调试,本地能调用到就行了,调试完成后再尝试修改代码并入开发环境,因此我们可以按照 如何允许访问非 SDK 接口? 中介绍的方法:

Android 10 及以上使用:

adb shell settings put global hidden_api_policy 1

Android 9 及以下使用:

adb shell settings put global hidden_api_policy_pre_p_apps  1
adb shell settings put global hidden_api_policy_p_apps 1

设置完成后再次运行代码,反射就能正常使用了,查阅日志变为了:

14:01:42.489 ReflectTest W  Accessing hidden method Landroid/net/EthernetManager;->getConfiguration(Ljava/lang/String;)Landroid/net/IpConfiguration; (max-target-r, reflection, allowed)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇