Android中的反射不起作用



我尝试使用反射使用自定义列表视图与目标api级别7的应用程序。必要的字段只能从api级别9中获得,所以我试图通过反射来修复这个问题。

我需要找到受保护的方法视图。overScrollBy (int, int, int, int, int, int, int, int,布尔型)。当我呼叫

View.getDeclaredMethods() 

和迭代方法[]数组我找到它,但当我尝试

View.class.getDeclaredMethod(String name, Class...< ? > paramTypes)
我得到一个NoSuchMethodException。我将硬编码的方法名称和参数类型值与从方法中提取的值(通过迭代找到)进行了比较,它们是相同的…
private boolean initCompatibility() 
{
Method[] methods = View.class.getDeclaredMethods();
try {
    // The name of the Method i am looking for;
    String OVERSCROLL_S = "overScrollBy";
    for (Method meth : methods) {
        if (meth.getName().equals(OVERSCROLL_S)) {
            mListView_overScrollBy = meth;
            break;
            // method found
        }
    }
    // Params for getDeclaredMethod(…)
    String methodName = "overScrollBy";
    Class[] methodParams =  {  Integer.TYPE, Integer.TYPE, Integer.TYPE, 
            Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE, 
            Integer.TYPE, Boolean.TYPE };
    // works
    Method test =  View.class.getDeclaredMethod(methodName,methodParams);
    // fails
    View.class.getDeclaredMethod(mListView_overScrollBy.getName(), 
               mListView_overScrollBy.getParameterTypes());
    /*
    * I also tried this way around and again the first worked and the second
    * failed, so the input arguments are not the problem...
    * View.class.getDeclaredMethod( mListView_overScrollBy.getName(), 
    *                           mListView_overScrollBy.getParameterTypes() );
    * Method test =  View.class.getDeclaredMethod(methodName,methodParams);
    */
    return true;
    } catch (SecurityException e) {
        e.printStackTrace();
        return false;
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
        return false;
    }
}

我不明白为什么调用总是第一次工作,第二次不。有趣的是,当我只调用View.class一次时,它也失败了。getDeclaredMethod(字符串名称,类…<?> paramTypes),它没有任何区别,我是否使用硬编码的输入值或从我正在寻找的方法中提取的值…

有谁知道是什么问题吗?由于

这很有趣,但我认为这不是android特有的。

我用普通Java写了这个小测试:

    public class ReflectionTest {
        public static void main(String[] args){
            Method[] m = ReflectionTest.class.getDeclaredMethods();
            for (Method method : m) {
                System.out.println(method.getName());
            }               
            try {
                Method m1 = ReflectionTest.class.getDeclaredMethod("d0", int.class, boolean.class);
                if(m1 != null){
                    System.out.println("m1 found!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } 
            try {
                Method m2 = ReflectionTest.class.getDeclaredMethod("d0", Integer.TYPE, Boolean.TYPE);
                if(m2 != null){
                    System.out.println("m2 found!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } 
            try {
                Class<?>[] carr = m[1].getParameterTypes();
                Method m3 = ReflectionTest.class.getDeclaredMethod("d0", carr);
                if(m3 != null){
                    System.out.println("m3 found!");
                }
            } catch (Exception e){
                e.printStackTrace();
            } 
        }
        public void d0(int a, boolean b){
        }
    }

在eclipse中,如果我调试它,将打印三个m1,m2和m3。但是,如果我运行它,在试图获得m3时抛出NoSuchMethodException

更新:

  • 在linux下使用jre 7测试运行,并且打印了所有三个m1,m2和m3。也许是jre6的问题?还是eclipse运行配置?
  • 更改carr声明使用方法0而不是Gray建议的1:Class<?>[] carr = m[0].getParameterTypes();。现在它运行正常,但在调试模式下抛出异常。这意味着返回数组m的方法顺序不同。
  • 更新#2确认,我已经包含了一个for循环来打印方法名。在运行模式下,方法数组的顺序与调试模式相反。

最新更新