Basic use of AOP

Resource link aspect.jar

Advantages: Using AOP can isolate various parts of business logic, thereby reducing the coupling between various parts of business logic , improving program reusability, and improving development efficiency

 The following is the most basic implementation to achieve aop development

1. Add the following code to the build.gradle in the app (bold part):

apply plugin: 'com.android.application'
//Aop needs to be compiled with its own compiler
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.aspectj:aspectjtools:1.8.8'
        classpath 'org.aspectj:aspectjweaver:1.8.8'
    }
}
android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"
    defaultConfig {
        applicationId "com.richard.aop"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile files('libs/aspectjrt.jar')
}

//The following code is to see the aspect print information
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;
            }
        }
    }
}

2. Add four buttons in the activity_main layout file, the code is as follows:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.richard.aop.MainActivity"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="mShake"
        android:text="Shake it" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="mAudio"
        android:text="Voice message" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="mVideo"
        android:text="video call" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="saySomething"
        android:text="Post a comment" />

</LinearLayout>

3. Handle the click events of the four buttons in the java code

    /**
     * Shake event
     * @param view
     */
    @BehaviorTrace("Shake it")
    public void mShake(View view) {

    }

    /**
     * Voice messages
     * @param view
     */
    @BehaviorTrace("Voice Message")
    public void mAudio(View view) {

    }

    /**
     * video call
     * @param view
     */
    @BehaviorTrace("Video call")
    public void mVideo(View view) {

    }

    /**
     * Post a talk
     * @param view
     */
    @BehaviorTrace("Post a talk")
    public void saySomething(View view) {


    }

4. Define an annotation class BehaviorTrace as follows: Then use these annotations on each button click callback method,

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BehaviorTrace {
    String value();
}

5. Write a facet class BehaviorTraceAspect:

/**
 * Created by Administrator on 2018/3/17 0017.
 */
@Aspect
public class BehaviorTraceAspect {
    public static final String TAG = "BehaviorTraceAspect";
    //Define the rules of the slice
    // is to add the place where the annotation was used before to the aspect
    @Pointcut("execution(@com.richard.aop.annotation.BehaviorTrace * *(..))")
    public void methodAnnotionWithBahaviorTrace(){}


    //2. How to deal with the content entering the slice
    //advice
    //@Before() runs before the pointcut
    //@After() runs after the pointcut
    //@Around() runs both before and after the pointcut
    @Around("methodAnnotionWithBahaviorTrace()")
    public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature  = (MethodSignature) joinPoint.getSignature();
        String className = signature.getDeclaringType().getSimpleName();
        String methodName = signature.getName();
        String funName = signature.getMethod().getAnnotation(BehaviorTrace.class).value();

        long begin = System.currentTimeMillis();//Start time
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        long duration = end - begin;
        Log.d("richard",String.format("Function name: %s, %s method of %s executed %d time", funName, className, methodName, duration));
        return result;
    }
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325602610&siteId=291194637