Отражение в Android не работает - PullRequest
2 голосов
/ 08 ноября 2011

Я попытался использовать отражение, чтобы использовать настраиваемое представление списка для приложения с целевым уровнем API 7. Необходимые поля доступны только с уровня API 9, поэтому я попытался исправить это с помощью отражения.

Мне нужно найти защищенный метод View.overScrollBy (int, int, int, int, int, int, int, int, boolean).Когда я вызываю

View.getDeclaredMethods() 

и перебираю массив Method [], я нахожу его, но когда я пытаюсь

View.class.getDeclaredMethod(String name, Class...< ? > paramTypes)

, я получаю NoSuchMethodException.Я сравнил жестко закодированные значения метода Name и parameterType со значениями, извлеченными из метода (найденными с помощью итерации), и они идентичны ...

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 (String name, Class ... <?> ParamTypes) и не имеет значения, использую ли я жестко закодированные входные значения или значение, извлеченное из методаЯ ищу ...

Кто-нибудь знает, в чем проблема?Спасибо

1 Ответ

1 голос
/ 08 ноября 2011

Это очень интересно, но я думаю, это не зависит от 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. Однако, если я запускаю его, NoSuchMethodException выбрасывается при попытке получить м3.

ОБНОВЛЕНИЕ:

  • Протестировано с jre 7 под linux, и все три m1, m2 и m3 были напечатаны. Возможно проблема в jre6? Или конфигурация запуска затмения?
  • Изменено объявление carr для использования метода 0 вместо 1: Class<?>[] carr = m[0].getParameterTypes();, как предложил Грей. Теперь он работает нормально, но выдает исключение в режиме отладки. Это означает другой порядок методов для возвращаемого массива m.
  • Обновление № 2 подтверждено, я включил цикл for для печати имен методов. В режиме выполнения порядок массива методов меняется по сравнению с режимом отладки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...