为什么 android/ Java 反射无法获取到私有方法,倒是能获取到 public 的方法

2022-01-04 16:39:19 +08:00
 nnegier

代码:

Method[] declaredMethods = Class.forName("android.widget.NumberPicker").getDeclaredMethods();
for (Method method:declaredMethods) {
	Logger.e(method.toString()); 
}

我查看了 Log ,一个 private 的方法都没有,google 百度无果,自行查询研究无果,特来求教,另外获取私有属性倒是正常的,就是私有方法不行。

问题来源,最开始是想获取单个私有方法,就是这个 validateInputTextView 私有方法,发现报错 NoSuchMethodException ,无论怎么获取测试都是这样,所以就决定把所有方法都打印出来,结果里面一个私有方法都没有。

4976 次点击
所在节点    Android
22 条回复
Jooooooooo
2022-01-04 16:42:52 +08:00
是不是引的包有冲突.
xia0pia0
2022-01-04 16:51:10 +08:00
Method method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
Object r = method.invoke(object);

SecurityManager 可能会拦截掉 setAccessible
nnegier
2022-01-04 17:40:54 +08:00
@Jooooooooo 正常运行
nnegier
2022-01-04 17:42:55 +08:00
@xia0pia0 关键是 getDeclaredMethods 里面就没有私有的方法,我全部打印出来看过了,setAccessible 、invoke 啥的都是后话了,前面就失败了
aguesuka
2022-01-04 18:07:43 +08:00
nnegier
2022-01-04 18:40:35 +08:00
@aguesuka 真实的类里有的。肯定是有的,它是私有方法,而且你看的那个链接也很能说明问题,那里展示的没有私有方法
junas7
2022-01-04 18:47:32 +08:00
私有方法写在 android.widget.NumberPicker 的父类?
janstk
2022-01-04 18:53:44 +08:00
hidden-api 限制?
nnegier
2022-01-04 19:01:26 +08:00
@junas7 不是,是自己类里定义的,我反复查过
nnegier
2022-01-04 19:02:08 +08:00
@janstk 不是,没有 hide ,关键是一个私有方法都获取不到
yescpu
2022-01-04 19:08:24 +08:00
怎么确定代码里面有?是不是 Android Studio 里面点源码里面看能看到这个方法?
但这不意味着 App 运行的 framework 中也一定有这个方法,如果你排除 hide 了的情况的话可能的原因是定制 rom 把这个方法干掉了。
e99unc1e
2022-01-04 19:10:20 +08:00
我刚刚在自己设备上也试了下,MIUI12 Android 9 ,也没有这个方法,有可能是编译的时候优化掉了吗。
codehz
2022-01-04 19:19:14 +08:00
你把 framework 从设备里提取出来反编译一下试试?
essicaj
2022-01-04 19:28:23 +08:00
一个 private 的方法都没有,确实有点奇怪。我试了下我手上的 android 11 的设备,和你一样的代码是能取到 validateInputTextView 这个方法的。或许和设备有点关系?
nnegier
2022-01-04 19:30:27 +08:00
e99unc1e
2022-01-04 19:34:55 +08:00
@nnegier 编译的时候可能会有部分方法被优化掉,比如内联之类的,源代码里面有不代表最终产物有。我赞成 13 楼的建议,吧 framework jar 之类的东西提取出来看看里面的情况。

另外我不太确定是不是内联的原因是,私有方法确实都没了。如果是仅仅被一次使用的私有方法没有出现,那被内联的可能性还是很大的,但是我看还有挺多是多处被使用的私有方法。
lxxself
2022-01-04 19:53:45 +08:00
蹲一个结果
yiranshaxiao
2022-01-04 22:00:00 +08:00
Accessing hidden method Landroid/widget/NumberPicker;->validateInputTextView(Landroid/view/View;)V (greylist-max-o, reflection, denied)
nnegier
2022-01-05 00:20:05 +08:00
@essicaj 把 targetSdkVersion 设置为 28 及以上,我的问题就能复现了
nnegier
2022-01-05 00:20:36 +08:00
@lxxself 散了吧,无解

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/826137

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX