[Из песочницы] Аспектно ориентированное программирование в Android

Услышав об аспектно ориентированном программировании я, как Android разработчик, сразу подумал, что на Android это вряд ли заработает, однако, решил попробовать. Я был очень удивлен, когда уже через 5 минут приложение, использующее AspectJ, успешно заработало на телефоне.Не буду убеждать в необходимости использования аспектов в Android и приводить примеры «uses cases», просто приведу пример того, как добавить к своему приложению возможность использования аспектов. Что такое аспекты и для чего их использовать прекрасно описано, например, на wiki.В качестве IDE для разработки я уже давно перешел на Android Studio, а следовательно использую gradle как систему сборки. Для нее и буду приводить пример конфигурирования.

Весь процесс подключения AspectJ состоит из следующих шагов:

Подключаем плагин для сборки: В разделе buildscript скрипта сборки вашего проекта добавляем в dependencies строку: classpath 'com.uphyca.gradle: gradle-android-aspectj-plugin:0.9.+' В build.gradle модуля приложения добавляем: apply plugin: «android-aspectj» …, а в зависимости модуля добавляем: dependencies { compile 'org.aspectj: aspectjrt:1.8.+' } Пишем сам аспект.Аспекты можно писать, используя специальный синтаксис, в файлах с расширением as, либо используя java + ряд анотаций. Поскольку Android Studio не включает AspectJ плагин, то я предпочел второй вариант (Для обладателей Ultimate версии IDEA доступны оба варианта): @Aspect public class MainActivityAspect { private static final String TAG = «helloaspectj»;

@Pointcut («execution (* ru.hoticecream.helloaspectj.ui.MainActivity.onCreate (…))») public void onCreateMethod (){}

@Before («onCreateMethod ()») public void doBeforeOnCreate (JoinPoint joinPoint) { Log.i (TAG, «AspectJ was here»); } } Данный аспект встраивается до вызова метода MainActivity.onCreate, выводя соответствующее сообщение в лог. Теперь, запустив приложение и открыв MainActivity, мы увидим в логе:… I/helloaspectj﹕ AspectJ was here

Приведу еще пример использования аспекта.Для этого в MainActivity добавим метод, устанавливающий определенному текстовому полю сообщение:

private TextView mGreetingText;

@Override protected void onCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); mGreetingText = (TextView) findViewById (R.id.greeting_message); setGreetingMessage («Hello Android»); }

private void setGreetingMessage (String message) { mGreetingText.setText (message); } Как видите, поле принимает значение «Hello Android», запустив приложение можно в этом убедиться;)Теперь добавим все в тот же класс аспекта следующие методы:

@Pointcut («execution (* ru.hoticecream.helloaspectj.ui.MainActivity.setGreetingMessage (…))») public void setGreetingMessageMethod (){}

@Around («setGreetingMessageMethod ()») public void makeNasty (final ProceedingJoinPoint pjp) throws Throwable { Log.d (TAG, pjp.getSignature ().toLongString ()); pjp.proceed (new Object[] { «Hello AspectJ» }); } В теперь этот аспект еще ищет метод setGreetingMessage и заменяет его вызов на содержимое метода makeNasty, используя для этого анотацию @AroundЗапустив приложение, мы уже увидим «Hello AspectJ». При этом MainActivity.java мы не изменяли.

На этом все. Надеюсь статья была вам полезна.

Напоследок пару ссылок:

© Habrahabr.ru