Правильный способ использования рефлексии унаследованных методов - PullRequest
2 голосов
/ 09 августа 2011

Я использовал класс TouchInterceptor в приложении Google Music в своем приложении. Этот класс позволяет перетаскивать элементы списка в разные позиции в списке.

Класс 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 (Method).

Я выполняю отладку на эмуляторе Android 2.2 (API 8), и, к сожалению, метод так и не найден. Я предполагаю, что getDeclaredMethods () не возвращает его в массиве, потому что smoothScrollBy - это метод AbsListView, который наследуется ListView и, в конечном счете, TouchInterceptor.

Я пытался привести это к AbsListView перед вызовом getClass (). GetDeclaredMethods (), но безуспешно.

Как я могу правильно получить smoothScrollBy, чтобы я мог вызвать его, когда доступно?

Обновление:

Я также пробовал следующее безрезультатно:

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

        }

Ответы [ 4 ]

1 голос
/ 10 августа 2011

Это потому, что это унаследованный метод.getDeclaredMethods() извлекает только методы, объявленные в вашем классе, а не методы его суперклассов.Хотя на самом деле я никогда не делал этого, вы сможете вызывать getSuperclass(), пока не найдете класс, который объявляет метод (AbsListView), и не получите метод из него.

Более простой ответ может быть просточтобы проверить версию API, хотя: Программно получить уровень API Android устройства?

0 голосов
/ 10 августа 2011

Спасибо за ваши ответы.Я решил проблему, выполнив следующее:

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

    }

У меня был список параметров метода, который я искал неправильно.

0 голосов
/ 10 августа 2011

Создайте метод с именем 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);
}
0 голосов
/ 10 августа 2011

Я не уверен, но я думаю, что если вы нацелите свое приложение на API 7, то метод не будет найден, потому что он не будет существовать. Вы можете указать API 8 и указать в своем манифесте, что вам требуется только уровень API 7.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...