2015-01-17 7 views
5

Мне нужно прокси-методы для разных классов классов в Android UI Framework, например TextView. В частности, TextView#setText(int resId). Этот метод не является частью интерфейса. Поэтому Java Proxy не будет работать, поскольку он работает только для интерфейсов. Мне нужно использовать манипуляции с байт-кодом.Прокси-окончательный метод в не финальном классе

Я нашел библиотеку под названием dexmaker, которая казалась многообещающей. Я предполагаю, что мне нужно выполнять манипулирование байтами времени выполнения, поскольку классы Android View фактически доступны на устройстве. Dexmaker может проксировать публичные методы для конкретных классов. Затем я заметил, что TextView#setText(int resId) необъяснимо final. Сам класс TextView не является окончательным.

Я думаю, что я мог использовать forx dexmaker для поддержки окончательных методов в не заключительных классах. Это возможно? Я не хочу запускать этот проект, если это не так. Это было бы огромной победой для моей библиотеки, хотя разработчикам не потребовалось бы подклассы, интерфейсы или ручные вызовы статических методов для их представлений. Моя библиотека должна знать, когда текст установлен в определенном представлении. Прокси-сервер - идеальный образец дизайна для этого.

+1

Случайный снимок (так как он не упоминается): Надувной макет позволяет [установить заводский класс] (http://developer.android.com/reference/android/view/LayoutInflater. html # setFactory2 (android.view.LayoutInflater.Factory2)), возможно, это то, что вам нужно. Это используется в [probe] (https://github.com/lucasr/probe/), где фабрика динамически создает прокси с помощью dexmaker для перехвата вызовов. –

+0

Часть моей библиотеки на самом деле использует макет надувной фабричной техники. Вы говорите, что вы можете настроить прокси-сервер там, на объектах представления, созданных через dexmaker? – jophde

+0

Большое спасибо Стефану. Источник зонда - именно то, что мне нужно :). Если я правильно понял, Probe создает совершенно новые классы View, поэтому ограничение Dexmaker Proxybuild на невозможность обработки окончательных методов не является проблемой? Из документов dexmaker ProxyBuilder: «Этот процесс работает только для классов с общедоступным и защищенным уровнем видимости». – jophde

ответ

2

Насколько я знаю, на Android это невозможно.

Dexmaker создает файлы dex, содержащие новые классы. Эти классы затем добавляются в приложение с помощью загрузчиков классов dex. Однако такие файлы dex не могут использоваться для замены классов, только для добавления новых подклассов, которые служат прокси.

В этом смысле dexmaker скорее напоминает cglib, чем javassist.

Обратите внимание, что Android не обеспечивает аналогичные возможности инструментария, как обычный Jvm, где вы можете отображать финальные классы и методы путем переопределения класса через агента. Это не предусмотрено Android: http://developer.android.com/reference/android/app/Instrumentation.html

2

Целью «окончательного» является то, что метод нельзя переопределить. Это фактически останавливает проксирование по расширению. Тем не менее, вы все еще можете использовать прокси-сервер, используя способ Spring.

Это одна из причин, почему лучше всего отделить интерфейс от реализации.

В более конкретном плане ...

// This snip is not supposed to be functional, only to demonstrate a concept 
interface TextViewInterface { 
    void setText (int resId); 
} 

class TextView implements TextViewInterface { 
    public final void setText (int resId) { 
    ... snip ... 
    } 
} 

class Proxy$TextView implements TextViewInterface 
extends View { // Added this for Android hierarchy 
    private TextView textView; 

    public void setText (int resId) { 
     textView.setText(resId); 
    } 
} 

ли эта помощь?

+0

Обычно это будет работать, но объекты должны войти в иерархию дерева просмотра Android, которая принимает только подклассы View или ViewGroup, и я уверен, что экземпляр используется в местах. Если я перейду из TextView, метод интерфейса будет мешать методу класса? – jophde

+0

Да, он не будет компилироваться, если я также продолжу TextView. Если только они использовали интерфейсы ... – jophde

+0

Механизм интерфейса позволяет вам обернуть метод класса. Вы можете расширить View (назовем его MyTextViewProxy) и обернуть TextView, если все, что расширяет View, приемлемо. Я обновил приведенный выше пример, чтобы показать расширенный вид. –

 Смежные вопросы

  • Нет связанных вопросов^_^