【问题标题】:Proper way to use reflection on inherited methods在继承方法上使用反射的正确方法
【发布时间】:2011-08-09 19:46:10
【问题描述】:

我在我的应用程序中使用了 Google 音乐应用程序中的 TouchInterceptor 类。此类允许您将列表项拖放到列表中的不同位置。

TouchInterceptor 类调用了一个名为 smoothScrollBy 的方法。此方法仅在 API 8+ 中可用。

我想在 API 7+ 上定位我的应用程序,所以我需要使用反射来执行 smoothScrollBy 只有当它存在时。

在 TouchInterceptor 的构造函数中,我添加了以下内容:

    Method[] ms = this.getClass().getDeclaredMethods();
    if (ms != null) {
        for (Method m : ms) {
            if (m != null && m.toGenericString().equals("smoothScrollBy")) {
                Class[] parameters = m.getParameterTypes();
                if (parameters != null && parameters.length == 1 && parameters[0].getName().equals("int")) {
                    mSmoothScrollBy = m;
                }
            }
        }
    }

这应该找到smoothScrollBy方法并将其分配给TouchInterceptor的一个新成员变量mSmoothScrollBy(方法)。

我正在 Android 2.2 (API 8) 模拟器上进行调试,不幸的是,该方法从未找到。我的猜测是 getDeclaredMethods() 不会在数组中返回它,因为 smoothScrollBy 是 AbsListView 的一个方法,它被 ListView 继承,最终被 TouchInterceptor 继承。

在调用 getClass().getDeclaredMethods() 之前,我尝试将其转换为 AbsListView,但没有成功。

如何正确获取 smoothScrollBy 以便在可用时调用它?

更新:

我也尝试了以下方法,但无济于事:

        Method test = null;
        try {
            test = this.getClass().getMethod("smoothScrollBy", new Class[] { Integer.class });
        }
        catch (NoSuchMethodException e) {

        }

【问题讨论】:

    标签: android reflection


    【解决方案1】:

    这是因为它是一个继承的方法。 getDeclaredMethods() 仅检索在 your 类中声明的方法,而不是其超类的方法。虽然我从未真正这样做过,但您应该可以调用getSuperclass(),直到找到声明该方法的类(AbsListView)并从中获取方法。

    一个更简单的答案可能只是检查 API 的版本:Programmatically obtain the Android API level of a device?

    【讨论】:

      【解决方案2】:

      我不确定,但我认为如果您将应用程序定位到 API 7,那么将找不到该方法,因为它不存在。您可以针对 API 8 并在清单中列出您只需要 API 级别 7。

      【讨论】:

        【解决方案3】:

        创建一个名为 hasMethod(Class cls, String method) 或类似的方法,它递归地调用自己的继承层次结构:

        public boolean hasMethod(Class cls, String method) {
            // check if cls has the method, if it does return true
            // if cls == Object.class, return false
            // else, make recursive call
            return hasMethod(cls.getSuperclass(), method);
        }
        

        【讨论】:

          【解决方案4】:

          感谢您的回复。我通过执行以下操作解决了这个问题:

              try {
                  mSmoothScrollBy = this.getClass().getMethod("smoothScrollBy", new Class[] { int.class, int.class });
              }
              catch (NoSuchMethodException e) {
          
              }
          

          我查找的方法的参数列表不正确。

          【讨论】:

            猜你喜欢
            • 2012-04-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-13
            • 1970-01-01
            • 2019-12-24
            • 2011-12-30
            相关资源
            最近更新 更多