AspectJ

AspectJ实际上是对AOP编程思想的一个实践,当然,除了AspectJ以外,还有很多其它的AOP实现,例如ASMDex,但目前最好、最方便的,依然是AspectJ。

AOP的用处非常广,从Spring到Android,各个地方都有使用,特别是在后端,Spring中已经使用的非常方便了,而且功能非常强大,但是在Android中,AspectJ的实现是略阉割的版本,并不是所有功能都支持,但对于一般的客户端开发来说,已经完全足够用了。

在Android上集成AspectJ实际上是比较复杂的,不是一句话就能compile,但是,鄙司已经给大家把这个问题解决了,大家现在直接使用这个SDK就可以很方便的在Android Studio中使用AspectJ了。Github地址如下:

https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx

另外一个比较成功的使用AOP的库是Jake大神的Hugo:

https://github.com/JakeWharton/hugo

AOP 能做什么?

持久化
性能监控
数据校验
缓存

1.引入 AspectJ

app/build.grade加入以下配置项,app和library配置相同:

import org.aspectj.bridge.IMessageimport org.aspectj.bridge.MessageHandlerimport org.aspectj.tools.ajc.Mainapply plugin: 'com.android.library'android {    compileSdkVersion 26    defaultConfig {        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'        }    }}repositories {    jcenter()    mavenCentral()}buildscript {    repositories {        jcenter()        mavenCentral()    }    dependencies {        classpath 'org.aspectj:aspectjtools:1.8.9'        // 如果是android library 要加上        classpath 'org.aspectj:aspectjweaver:1.8.9'    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    compile 'org.aspectj:aspectjrt:1.8.9'//    compile 'com.android.support:appcompat-v7:27.1.1'}android.libraryVariants.all { variant ->    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", android.bootClasspath.join(                File.pathSeparator)]        MessageHandler handler = new MessageHandler(true)        new Main().run(args, handler)        def log = project.logger        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:                case IMessage.INFO:                    log.info message.message, message.thrown                    break                case IMessage.DEBUG:                    log.debug message.message, message.thrown                    break            }        }    }}

2.AspectJ 语法

JPoint:代码可注入的点,比如一个方法的调用处或者方法内部、“读、写”变量等。
Pointcut:用来描述 JPoint 注入点的一段表达式,比如:调用 Animal 类 fly 方法的地方,call(* Animal.fly(..))。
Advice:常见的有 Before、After、Around 等,表示代码执行前、执行后、替换目标代码,也就是在 Pointcut 何处注入代码。
Aspect:Pointcut 和 Advice 合在一起称作 Aspect。

3.使用

统计一下某个方法的运行时间

public class StopWatch {    private long startTime;    private long endTime;    private long elapsedTime;    public StopWatch() {        //empty    }    private void reset() {        startTime = 0;        endTime = 0;        elapsedTime = 0;    }    public void start() {        reset();        startTime = System.nanoTime();    }    public void stop() {        if (startTime != 0) {            endTime = System.nanoTime();            elapsedTime = endTime - startTime;        } else {            reset();        }    }    public long getTotalTimeMillis() {        return (elapsedTime != 0) ? TimeUnit.NANOSECONDS.toMillis(endTime - startTime) : 0;    }}
public class DebugLog {    private DebugLog() {}    /**     * Send a debug log message     *     * @param tag Source of a log message.     * @param message The message you would like logged.     */    public static void log(String tag, String message) {//        Log.i(tag, message);        System.out.print(message);    }}
@Retention(RetentionPolicy.CLASS)@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD })public @interface DebugTrace {}
@Aspectpublic class TraceAspect {    private static final String POINTCUT_METHOD =            "execution(@com.example.libraryaspectj.DebugTrace * *(..))";    private static final String POINTCUT_CONSTRUCTOR =            "execution(@com.example.libraryaspectj.DebugTrace *.new(..))";    @Pointcut(POINTCUT_METHOD)    public void methodAnnotatedWithDebugTrace() {}    @Pointcut(POINTCUT_CONSTRUCTOR)    public void constructorAnnotatedDebugTrace() {}    @Around("methodAnnotatedWithDebugTrace() || constructorAnnotatedDebugTrace()")    public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();        String className = methodSignature.getDeclaringType().getSimpleName();        String methodName = methodSignature.getName();        final StopWatch stopWatch = new StopWatch();        stopWatch.start();        Object result = joinPoint.proceed();        stopWatch.stop();        DebugLog.log(className, buildLogMessage(methodName, stopWatch.getTotalTimeMillis()));        Log.i("*** yang",buildLogMessage(methodName, stopWatch.getTotalTimeMillis()));        return result;    }    /**     * Create a log message.     *     * @param methodName A string with the method name.     * @param methodDuration Duration of the method in milliseconds.     * @return A string representing message.     */    private static String buildLogMessage(String methodName, long methodDuration) {        StringBuilder message = new StringBuilder();        message.append("methodName --> ");        message.append(methodName);        message.append(" --> ");        message.append("[");        message.append(methodDuration);        message.append("ms");        message.append("]");        return message.toString();    }}

然后在app中的某activity

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

即会打印出 I/* yang: Libraryaspectj –> onCreate –> [82ms]

以上就是对aspectj的简单实现后续展开都是遵循aspectj语法的使用

aspecjt文档

更多相关文章

  1. Android中执行java命令的方法及java代码执行并解析shell命令
  2. Android中,在C++层使用TinyXML解析XML文件
  3. Android(安卓)MP4取得播放时长的方法
  4. 如何保证Android设备的安全性
  5. 浅谈Java中Collections.sort对List排序的两种方法
  6. 箭头函数的基础使用
  7. NPM 和webpack 的基础使用
  8. Python list sort方法的具体使用
  9. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程

随机推荐

  1. android系统权限大全
  2. android Activity单元测试
  3. Android(安卓)如何使用internal 和 hidde
  4. Cocos2dx setup Eclipse environment for
  5. Android四种布局
  6. Android(安卓)FTP客户端使用,快速上传文件
  7. Android(安卓)MediaProvider详解(基础篇)
  8. Android(安卓)远程监控摄像头 移动端+PC
  9. Intent在Android中的几种用法
  10. android:clipChildren属性的分析——是否