Aspect oriented programming: the use of aspectJ in Android

1, Introduction and usage scenarios

aspectJ It is an open source tool in the eclipse community. It can seamlessly expand the aspect oriented java programming language and is fully compatible with the java language. It can gracefully deal with the concerns, such as error checking and processing, performance optimization, monitoring and logging. When it comes to aspect oriented programming, you may think of the famous spring AOP, which is implemented based on the dynamic proxy pattern. The agent mode is divided into static agent and dynamic agent. The static agent modifies the code during compilation and injects the specified object into the code, which has poor expansibility and strong coupling; The dynamic agent dynamically obtains objects and calls their methods through reflection at runtime, which is inefficient and highly coupled. Spring AOP solves the coupling problem to a certain extent through IOC dependency injection technology, but the execution efficiency has not been solved; aspectJ modifies the code during compilation and is separated from the business logic code. It has strong coupling and does not affect the efficiency of runtime. JakeWharton Great God's function is time-consuming to monitor open source projects hugo aspectJ technology is used.

2, Basic concepts

2.0 notes

stay Manually implement bindview An article uses annotations. Now more and more people feel that annotations are very useful. For the specific use of annotations, please refer to my previous articles annotation Here I create a runtime annotation.

//CheckNet.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CheckNet {
}

2.1 Aspect

Aspect is a collection of pointcuts and notifications, @ aspect uses it to declare a class to represent an aspect that needs to be executed. For example, I create a class here and add @ aspect annotation at the top of the class.

//MyAspect.java
@Aspect
public class MyAspect {
}

2.2 PointCut entry point

Pointcuts, also known as trigger conditions, refer to those connection points that want to cut into Advice filtered by using some specific expressions, @ Pointcut declares a Pointcut.

 

 

 

 

 

 

 

 

 

  

 

Here I want to make a logic of network judgment

//MyAspect.java
@Pointcut("execution(@com.shan.aspectjapp.CheckNet * *(..))")
public void checkNetAction(){

}

In Pointcut, I use execution, that is, taking the execution time of the method as the tangent point to trigger the Aspect class. The string in execution is a trigger condition and a specific cut-off point. Let me explain the composition of the parameters. "execution(@com.shan.aspectjapp.CheckNet * *(..))" This condition is that all methods or attributes annotated with checknet will be tangent points, with a wide range.

  • **: indicates any package name
  • ..: represents any number of parameters of any type

2.3 Advice notice

Notification is the code implementation method injected into the pointcut, @ Before/@After/@Around / (collectively referred to as Advice type) declares that the slice code is executed before, after and in the tangent point. See the following table for details:

Before

Pre notification: the notification is executed before the target is executed

After

Post notification

Around

Surround the notice, execute the notice in the target execution, and control the target execution time

AfterReturning

The post return notification is executed when the target returns

AfterThrowing

Exception notification, which is executed when the target throws an exception

Here @ Around is used to judge whether there is a network when the object code is executed. If there is no network, the target method will not be executed, otherwise the target method will be executed

@Around("checkNetAction()")
public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable {
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);
    LogUtil.d("checkNet,"+checkNet);
    if (checkNet!=null) { 
        if (!isNetworkAvailable()) {
            Toast.makeText(MyApp.getContext(),"please check your network",Toast.LENGTH_SHORT).show();
            return null; //If there is no network, the target method will not continue to execute
        }
    }
    return joinPoint.proceed(); //If there is a network, continue to execute the target method
}

2.4 Joint Point

All target methods are join points

2.5 Weaving weaving

It mainly uses AJC to inject the cutting code into the target at compile time and generate the mixed code class process

3, Used in android

3.1 download and install aspectJ

You can download aspectJ.com from aspectJ's official website jar, and then two computers go all the way to next until the installation is successful. I downloaded version 1.9.6 here. After installation, I found aspectjrt. Com in the installation directory jar will be used later in android project.

 

 

3.2 configuring android dependencies

First, the project root directory build Add aspectJ dependency to gradle

//build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ......
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        //The focus is on the following two lines
        classpath 'org.aspectj:aspectjtools:1.9.6'
        classpath 'org.aspectj:aspectjweaver:1.9.6'
    }
}

 

Then, in the build.exe of the main module Gradle add dependencies and environments

//build.gradle
plugins {
    id 'com.android.application'
}
//Focus on the following three lines
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
......
//Then there's a lump down there
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;
            }
        }
    }
}

Finally, aspectjrt Put jar in libs directory and add dependency

3.3 use

Then click login in activity. If there is no network, the following "we will surf the Internet" prompt will not go to, but myaspect "please check your network" in Java; If there is a network, you will be prompted "we will surf the Internet"

//MainActivity.java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    @CheckNet //This is aspect oriented programming
    public void login(View view) {
        Toast.makeText(this,"we will surf the Internet",Toast.LENGTH_SHORT).show();
    }
}

Reference:

Android AOP, an essential for Android architects, is a detailed explanation of aspect oriented programming, which is super practical!

 

Keywords: Java

Added by misterm on Fri, 28 Jan 2022 19:16:24 +0200