AspectJ在Android中使用(AOP)
AOP(Aspect Oriented Programming)切面編程在處理一些與業務邏輯無關,但在很多地方又不得不添加相關邏輯代碼,可以很好的解決相關問題,比如在Android中有些地方需要打LOG日志,或者在某些地方需要檢查系統權限等,可以很好的解決這類問題。
而AOP中主要使用的就是AspectJ,AspectJ有自己相關的一套語法,大致和JAVA類似。官方簡介
那么在AndroidStudio 中要怎么使用AOP呢?
首先需要新建一個module,方便引入相關的AspectJ配置,便于在其中編寫與業務邏輯無關緊要,并且在代碼中經常出現的常用代碼, 之后在module下的build.gradle中 導入AspectJ的dependences
compile ‘org.aspectj:aspectjrt:1.8.9’ 復制代碼并在build.gradle根下配置
repositories {mavenCentral() }buildscript {repositories {mavenCentral()}dependencies {classpath 'com.android.tools.build:gradle:2.1.3'classpath 'org.aspectj:aspectjtools:1.8.9'classpath 'org.aspectj:aspectjweaver:1.8.9'} }android.libraryVariants.all { variant ->LibraryPlugin plugin = project.plugins.getPlugin(LibraryPlugin)JavaCompile javaCompile = variant.javaCompilejavaCompile.doLast {String[] args = ["-showWeaveInfo","-1.5","-inpath", javaCompile.destinationDir.toString(),"-aspectpath", javaCompile.classpath.asPath,"-d", javaCompile.destinationDir.toString(),"-classpath", javaCompile.classpath.asPath,"-bootclasspath", plugin.project.android.bootClasspath.join(File.pathSeparator)]MessageHandler handler = new MessageHandler(true);new Main().run(args, handler)def log = project.loggerfor (IMessage message : handler.getMessages(null, true)) {switch (message.getKind()) {case IMessage.ABORT:case IMessage.ERROR:case IMessage.FAIL:log.error message.message, message.thrownbreak;case IMessage.WARNING:case IMessage.INFO:log.info message.message, message.thrownbreak;case IMessage.DEBUG:log.debug message.message, message.thrownbreak;}}} } 復制代碼以上module的build.gradle 配置主要是搭建AspectJ運行環境
之后在app下的build.gradle添加module的依賴,并且添加如下配置
repositories {mavenCentral() } buildscript {repositories {mavenCentral()}dependencies {classpath 'org.aspectj:aspectjtools:1.8.9'} }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.javaCompilejavaCompile.doLast {String[] args = ["-showWeaveInfo","-1.5","-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.thrownbreak;case IMessage.WARNING:log.warn message.message, message.thrownbreak;case IMessage.INFO:log.info message.message, message.thrownbreak;case IMessage.DEBUG:log.debug message.message, message.thrownbreak;}}} } 復制代碼以上配置主要是將app和module關聯起來。
然后在module中創建TestAspectJ類, 具體代碼如下:
package com.clayx.org.aspectj;import android.annotation.TargetApi; import android.os.Build; import android.util.Log;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut;/*** Created by Administrator on 2016/9/2.*/ @Aspect public class TestAspectJ {private static final String METHOD_EXECUTION = "execution(* *..MainActivity+.onCreate(..))";private static final String METHOD_CALL = "call(* *..MainActivity+.test(..)) && args(name)";private String TAG = "Clayx";@Pointcut(METHOD_EXECUTION)public void methodExecution() {}@Pointcut(METHOD_CALL)public void methodCall(String name) {}@Around("methodExecution()")public void aroundMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {joinPoint.proceed();String result = "-----------------------------MethodExecution";Log.e(TAG, result);}@Around("methodCall(String)")public Object arouneMethodCall(ProceedingJoinPoint joinPoint){String name = (String) joinPoint.getArgs()[0];Log.e(TAG,name);return name;}} 復制代碼運行APP,打印出Log如下:
對于注解的使用,可以更好的和AspectJ結合使用,
注解類如下:
package com.clayx.org.aspectj.anno;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** Created by Administrator on 2016/9/2.*/ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAspectJ {} 復制代碼注解相關的AspectJ的實現類
package com.clayx.org.aspectj.anno;import android.content.Context; import android.widget.Toast;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut;/*** Created by Administrator on 2016/9/2.*/@Aspect public class TestAspect {@Pointcut("execution(@TestAspectJ private * *..*.*(..))")public void testAspect() {}@Around("testAspect()")public void testTestAspect(ProceedingJoinPoint joinPoint) {Toast.makeText((Context) joinPoint.getTarget(), "OK", Toast.LENGTH_SHORT).show();}} 復制代碼注解運行如下:
轉載于:https://juejin.im/post/5a6181476fb9a01c9064f18c
總結
以上是生活随笔為你收集整理的AspectJ在Android中使用(AOP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL中什么是数据表的复合主键
- 下一篇: Android 音视频深入 四 录