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; } }