nnegier
V2EX  ›  Android

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

  •  1
     
  •   nnegier · Jan 4, 2022 · 13642 views
    This topic created in 1594 days ago, the information mentioned may be changed or developed.

    代码:

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

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

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

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

    不是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  
       Jan 4, 2022
    是不是引的包有冲突.
    xia0pia0
        2
    xia0pia0  
       Jan 4, 2022
    Method method = object.getClass().getDeclaredMethod(methodName);
    method.setAccessible(true);
    Object r = method.invoke(object);

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

    另外我不太确定是不是内联的原因是,私有方法确实都没了。如果是仅仅被一次使用的私有方法没有出现,那被内联的可能性还是很大的,但是我看还有挺多是多处被使用的私有方法。
    lxxself
        17
    lxxself  
       Jan 4, 2022
    蹲一个结果
    yiranshaxiao
        18
    yiranshaxiao  
       Jan 4, 2022
    Accessing hidden method Landroid/widget/NumberPicker;->validateInputTextView(Landroid/view/View;)V (greylist-max-o, reflection, denied)
    nnegier
        19
    nnegier  
    OP
       Jan 5, 2022
    @essicaj 把 targetSdkVersion 设置为 28 及以上,我的问题就能复现了
    nnegier
        20
    nnegier  
    OP
       Jan 5, 2022
    @lxxself 散了吧,无解
    nnegier
        21
    nnegier  
    OP
       Jan 5, 2022
    @junas7 android 官方的限制
    nnegier
        22
    nnegier  
    OP
       Jan 5, 2022
    @yiranshaxiao 高手
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   849 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 62ms · UTC 21:06 · PVG 05:06 · LAX 14:06 · JFK 17:06
    ♥ Do have faith in what you're doing.