【问题标题】:IllegalAccessException: Try to access hidden class using reflectionIllegalAccessException:尝试使用反射访问隐藏类
【发布时间】:2018-07-09 22:59:14
【问题描述】:

我正在尝试从以下位置创建 StatusBarManager 的实例: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r1/android/app/StatusBarManager.java#StatusBarManager

这是我用来执行此操作的代码:

    try {
        Class<?> c = Class.forName("android.app.StatusBarManager");
        Object object = c.getDeclaredConstructor(Context.class).newInstance(context);

        Method m = c.getDeclaredMethod("expandNotificationsPanel",(Class<?>[]) null);
        try {
            m.invoke(object, (Object[]) null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

但是,我在尝试创建构造函数时遇到了 IllegalAccessException。有关如何进行此操作的任何指导?

【问题讨论】:

    标签: java android


    【解决方案1】:

    StatusBarManager 只能由其包中的其他类构造(例如,它是 package-private)。这意味着您需要通过其他方法访问它。

    【讨论】:

      【解决方案2】:

      你需要使用setAccessible(true)

      对我来说,这段代码编译正确:

      try {
          //get the Class for the StatusBarManager
          Class className = Class.forName("android.app.StatusBarManager");
          Constructor constructor = className.getDeclaredConstructor(Context.class);
          Method m = className.getDeclaredMethod("expandNotificationsPanel",(Class<?>[]) null);
          //set the constructor accessible and build an instance of it
          constructor.setAccessible(true);
          Object statusBarManager = constructor.newInstance(context);
          //invoke the method
          m.invoke(statusBarManager, (Object[]) null);
      } catch (InstantiationException | 
               InvocationTargetException |
               NoSuchMethodException |
               IllegalAccessException |
               ClassNotFoundException e) {
                  e.printStackTrace();
      }
      

      免责声明:如果您这样做,您必须知道您的代码可以闯入 任何时候使用不同的 Android 版本或在 Android(s) 中使用自定义 由 OEM 实施。

      【讨论】:

      • @TerrelLewis 请接受约翰的回答,他应得的。
      【解决方案3】:

      我的第一个倾向是说“不要那样做”。具体来说,不要尝试访问或使用平台 API 的私有类、方法、构造函数或字段,也不要尝试访问或使用任何第三方 API 的私有类、方法、构造函数或字段。您打算使用的类和成员是public,或最多protected

      假设您无论如何都要坚持继续,如果您想调用一个您通常无法访问的构造函数,那么正如您所发现的那样,反射不会自动授予您访问权限。但是您可以反射性地获得访问权限。要通过该私有构造函数反射性地实例化该类,您需要先在 Constructor 对象上调用 setAccessible(true),然后再调用 newInstance()

      【讨论】:

      • 班级is public。它的构造函数是包私有的
      • 谢谢@MatPag,我已经更准确地修改了针对情况的答案。当然底线——使用setAccessible(true)——保持不变。
      猜你喜欢
      • 2015-09-24
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      相关资源
      最近更新 更多