为什么 android/ Java 反射无法获取到私有方法,倒是能获取到 public 的方法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nnegier
V2EX    Android

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

  •  1
     
  •   nnegier 2022-01-04 16:39:19 +08:00 12876 次点击
    这是一个创建于 1458 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码:

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

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

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

    第 1 条附言    2022-01-04 19:03:17 +08:00
    有热心的 android 开发可以复制到程序中运行看看
    第 2 条附言    2022-01-04 20:19:48 +08:00
    谢谢各位,得知一位朋友运行成功我才意识到了代码没有问题,随即我也在 Windows 上的 Android Studio 上运行成功。所以某种程度上我问了一个不是问题的问题,我感到很抱歉。但我出现问题的环境是 Kubuntu 上的 Android Studio ,我反复验证了,依旧失败,我平常在 Kubuntu 上开发,因为 Windows 我感觉不太稳定,动不动给我蓝屏,鉴于我之前解决过一次蓝屏,再鉴于此次事件,以及 Kubuntu 软件方面的缺乏,所以我决定要换回 Windows 开发环境了,算是自动绕开了这个问题吧。Kubuntu 我用了蛮久,也用它开发主要的项目,挺喜欢的,经此一事,咱们以后还是在虚拟机里见吧,再见。
    第 3 条附言    2022-01-05 00:17:48 +08:00

    不是Kubuntu的问题,这个问题是Google Android的问题,而且正因为如此无解,Google在Android 9(API 级别 28)加了限制,无法访问私有方法,当然targetSdkVersion低于28是可以的,往上就不行。

    我很气愤,它限制这个做啥?说什么提高稳定性,他就觉得要用到反射来做些事情的人是菜鸟吗,我实说我是想帮它NumberPicker优化点逻辑,细节方面不到位,我给其私有字段设置了监听器,然后还需要用到一个私有方法,于是就有了今天的问题。

    真的很气人。

    https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces

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

    另外我不太确定是不是内联的原因是,私有方法确实都没了。如果是仅仅被一次使用的私有方法没有出现,那被内联的可能性还是很大的,但是我看还有挺多是多处被使用的私有方法。
    lxxself
        17
    lxxself  
       2022-01-04 19:53:45 +08:00
    蹲一个结果
    yiranshaxiao
        18
    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
        19
    nnegier  
    OP
       2022-01-05 00:20:05 +08:00
    @essicaj 把 targetSdkVersion 设置为 28 及以上,我的问题就能复现了
    nnegier
        20
    nnegier  
    OP
       2022-01-05 00:20:36 +08:00
    @lxxself 散了吧,无解
    nnegier
        21
    nnegier  
    OP
       2022-01-05 00:21:00 +08:00
    @junas7 android 官方的限制
    nnegier
        22
    nnegier  
    OP
       2022-01-05 00:21:21 +08:00
    @yiranshaxiao 高手
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     802 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 22:02 PVG 06:02 LAX 14:02 JFK 17:02
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86