Аспектно ориентированное программирование в Android

от автора

Услышав об аспектно ориентированном программировании я, как Android разработчик, сразу подумал, что на Android это вряд ли заработает, однако, решил попробовать. Я был очень удивлен, когда уже через 5 минут приложение, использующее AspectJ, успешно заработало на телефоне.

Не буду убеждать в необходимости использования аспектов в Android и приводить примеры «uses cases», просто приведу пример того, как добавить к своему приложению возможность использования аспектов. Что такое аспекты и для чего их использовать прекрасно описано, например, на wiki.

В качестве IDE для разработки я уже давно перешел на Android Studio, а следовательно использую gradle как систему сборки. Для нее и буду приводить пример конфигурирования.

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

  1. Подключаем плагин для сборки:
    В разделе buildscript скрипта сборки вашего проекта добавляем в dependencies строку:
    classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.+'

  2. В build.gradle модуля приложения добавляем:
    apply plugin: "android-aspectj"

  3. … а в зависимости модуля добавляем:
    dependencies {     compile 'org.aspectj:aspectjrt:1.8.+' } 

  4. Пишем сам аспект.
    Аспекты можно писать, используя специальный синтаксис, в файлах с расширением 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</nasty>, используя для этого анотацию <code>@Around

Запустив приложение, мы уже увидим «Hello AspectJ». При этом MainActivity.java мы не изменяли.

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

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

ссылка на оригинал статьи http://habrahabr.ru/post/231287/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *