Aspect Oriented Programming in Android
Having heard about aspect-oriented programming, I, as an Android developer, immediately thought that it was unlikely to work on Android, however, I decided to give it a try. I was very surprised when after 5 minutes an application using AspectJ successfully worked on the phone.
I won’t convince of the need to use aspects in Android and give examples of “uses cases”, I’ll just give an example of how to add the possibility of using aspects to my application. What are aspects and why use them is well described, for example, on the wiki .
As an IDE for development, I switched to Android Studio a long time ago, and therefore I use gradle as a build system. For her, I will give an example of configuration.
The entire AspectJ connection process consists of the following steps:
Now, by launching the application and opening MainActivity, we will see in the log:
I will give another example of the use of the aspect.
To do this, add a method to MainActivity that sets a message to a specific text field:
As you can see, the field takes the value “Hello Android”, starting the application you can see this;)
Now we add all the following methods to the same aspect class:
Now, this aspect is still looking for a method
Running the application, we will already see “Hello AspectJ”. At the same time,
That's all. I hope the article was useful to you.
Finally, a couple of links:
I won’t convince of the need to use aspects in Android and give examples of “uses cases”, I’ll just give an example of how to add the possibility of using aspects to my application. What are aspects and why use them is well described, for example, on the wiki .
As an IDE for development, I switched to Android Studio a long time ago, and therefore I use gradle as a build system. For her, I will give an example of configuration.
The entire AspectJ connection process consists of the following steps:
- We connect the plug-in for assembly:
In the section ofbuildscript
the build script of your project, add to thedependencies
line:classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.+'
- In
build.gradle
the application module add:apply plugin: "android-aspectj"
- ... and depending on the module, add:
dependencies { compile 'org.aspectj:aspectjrt:1.8.+' }
- We write the aspect itself.
Aspects can be written using special syntax in files with the as extension, or using java + a number of annotations. Since Android Studio does not include the AspectJ plugin, I preferred the second option (For owners of the Ultimate version of IDEA, both options are available):@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"); } }
This aspect is embedded before the method callMainActivity.onCreate
, displaying the corresponding message in the log.
Now, by launching the application and opening MainActivity, we will see in the log:
... I/helloaspectj﹕ AspectJ was here
I will give another example of the use of the aspect.
To do this, add a method to MainActivity that sets a message to a specific text field:
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);
}
As you can see, the field takes the value “Hello Android”, starting the application you can see this;)
Now we add all the following methods to the same aspect class:
@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" });
}
Now, this aspect is still looking for a method
setGreetingMessage
and replaces its call with the contents of the method makeNasty
, using the annotation for this. @Around
Running the application, we will already see “Hello AspectJ”. At the same time,
MainActivity.java
we did not change. That's all. I hope the article was useful to you.
Finally, a couple of links:
- For the fact that everything was so simple it is worth saying thanks to the author of the plugin for gradle:
github.com/uPhyca/gradle-android-aspectj-plugin - An interesting lecture on AspectJ, which tells about examples of use and features of the library:
www.youtube.com/watch?v=X_QJMKEgJBk&index=3&list=PLCA5CB42F5A816A17 - And finally, the source code for an example from this article:
github.com/HotIceCream/helloaspectj