What is AOP
The following is an introduction to AOP on Wikipedia:
Aspect oriented programming (AOP) is a programming idea in computer science, which aims to further separate crosscutting concerns from business subjects, so as to improve the modularization of program code. By adding an additional Advice mechanism to the existing code, the code blocks declared as "pointcuts" can be uniformly managed and decorated, such as "adding background logs to all methods whose method names begin with 'set *". This idea enables developers to add functions (such as log function) that are not closely related to the core business logic of the code to the program without reducing the readability of the business code. Aspect oriented programming idea is also the basis of aspect oriented software development.
Aspect oriented programming divides code logic into different modules (i.e. concerns, a specific logical function). Almost all programming ideas involve the classification of code functions, encapsulating each Concern into independent abstract modules (such as functions, procedures, modules, classes and methods), which can be further implemented, encapsulated and rewritten. Some concerns "crosscutting" several modules in the program code, that is, they appear in multiple modules, which are called crosscutting concerns (horizontal concerns).
What is AspectJ
The following is an introduction to AspectJ on Wikipedia:
AspectJ is in PARC Aspect oriented programming (AOP) extensions created for the Java programming language. It's in Eclipse Foundation Available in open source projects, it can be used independently or integrated into Eclipse. By emphasizing the simplicity and usability of end users, AspectJ has become a widely used AOP de facto standard. Since its first public release in 2001, it uses Java like syntax and includes IDE integration for displaying crosscutting structures.
Use of AspectJ in Android
This article mainly records the use of AspectJ in Android, so it will not record the knowledge points related to the installation of AspectJ and the compilation of aj files using AspectJ. If you need to understand this knowledge, you can refer to the knowledge written by Mr. Deng Fanping In depth understanding of Android AOP.
The following is an example to illustrate the use of AspectJ in Android:
For example, we want to start printing a line of log in the onCreate life cycle method of an Activity. Of course, you can directly code it, but if you use AspectJ aspect oriented programming, you can do this:
- Build. In the root directory of the Android project Add the following code to the gradle file
dependencies { classpath "com.android.tools.build:gradle:4.2.2" classpath 'org.aspectj:aspectjtools:1.9.7' classpath 'org.aspectj:aspectjweaver:1.9.7' }
- In APP / build Add the following code to the gradle file
android { ... } dependencies { implementation 'org.aspectj:aspectjrt:1.9.7' ... } import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main final def log = project.logger final def variants = project.android.applicationVariants variants.all { variant -> if (!variant.buildType.isDebuggable()) { log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.") return; } JavaCompile javaCompile = variant.javaCompile javaCompile.doLast { String[] args = ["-showWeaveInfo", "-1.8", "-inpath", javaCompile.destinationDir.toString(), "-aspectpath", javaCompile.classpath.asPath, "-d", javaCompile.destinationDir.toString(), "-classpath", javaCompile.classpath.asPath, "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)] log.debug "ajc args: " + Arrays.toString(args) MessageHandler handler = new MessageHandler(true); new Main().run(args, handler); for (IMessage message : handler.getMessages(null, true)) { switch (message.getKind()) { case IMessage.ABORT: case IMessage.ERROR: case IMessage.FAIL: log.error message.message, message.thrown break; case IMessage.WARNING: log.warn message.message, message.thrown break; case IMessage.INFO: log.info message.message, message.thrown break; case IMessage.DEBUG: log.debug message.message, message.thrown break; } } } }
- Create a Java class and annotate it with @ Aspect, as shown in the following code
import android.util.Log; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class MethodAspect { private static final String TAG = "MethodAspect"; @Pointcut("execution(* com.example.testaspectj.MainActivity.onCreate(..))") public void jointPoint() {} @Before("jointPoint()") public void beforeOnCreate() { Log.e(TAG, "this message is printed before onCreate..."); } }
- Run the code to start MainActivity. MainActivity directly uses the code when creating a new Android project without making any changes. After the program runs, the console will print as follows:
In the app/build/intermediates/javac/debug/classes / directory, you can see mainactivity Class file, decompiled by Android studio, the source code is as follows:
You can see that a new line of code is inserted into the onCreate method:
MethodAspect.aspectOf().beforeOnCreate();
AspectJ knowledge points
AspectJ terminology
- JointPoint: the point where code can be injected, such as the calling place of a method or inside the method, "read, write" variables, etc.
- Pointcut: an expression used to describe the JPoint injection point. For example, where the fly method of Animal class is called, call(* Animal.fly(...)).
- Advice: Before, After, Around, etc. are common, indicating that the target code is replaced Before and After code execution, that is, where the code is injected into the Pointcut.
- Aspect: Pointcut and Advice together are called aspect.
AspectJ syntax
Signature reference in Pointcut:
The above Signature is composed of an expression, and there is a "space" between each keyword. The following is the explanation of the keyword:
Once you are familiar with Pointcut syntax, Advice is very simple. It includes the following:
AspectJ applications in Android can also use this open source library: https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx This library simplifies the threshold of using AspectJ directly in Android projects, but there are requirements for the version of gradle plug-in (the maximum version of gradle plug-in currently supported is 3.6.1)