Android AOP(AspectJ)编程入门

AOP,即面向切面编程。
定义:

把某一方面的一些功能提取出来与一批对象进行隔离,提取之后我们就可以对某个单方面的功能进行编程。

举个例子,app中许多功能都必须要求用户手机联网才能进行。写代码的时候,我们得加上判断:

if(能联网)
    balabala..
else
    提示用户检查手机网络

显然,这段逻辑需要重复写很多次,而aop的作用就是将你从不断的重复劳动中解放出来。
这里我们需要借助第三方的编译工具 AspectJ

下载aspectj 地址: http://www.eclipse.org/aspectj/downloads.php
选择一个版本下载完成后解压出里面的

image.png

放到libs中并添加至项目依赖:
image.png

修改build.gradle:

apply plugin: 'com.android.application'
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.aspectj:aspectjtools:1.8.9'
        classpath 'org.aspectj:aspectjweaver:1.8.9'
    }
}

repositories {
    mavenCentral()
}

android {
    ...
}

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

dependencies {
    ...
}

至此aspectJ配置完成。

下面介绍AspectJ如何处理切面,以判断手机网络是否连通为例:

1、自定义一个注解,作用目标为方法。被注解的方法即为切点。

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

}

2、处理切面逻辑

@Aspect
public class CheckNetAspect {

    /**
     *  找到处理切点,即切点注解
     *  * *代表所有方法,(..)代表所有参数,这里可以根据具体的方法类型来做处理
     */
    @Pointcut("execution(@com.android.pronetway.SchoolGoods.ioc.CheckNet * *(..))")
    public void insertBehvior() {

    }

    /**
     * 如何处理切面
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("insertBehvior()")
    public Object dealPont(ProceedingJoinPoint joinPoint) throws Throwable {
        final MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        final CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);
        if (checkNet != null) {
            final boolean connected = NetworkUtils.isConnected();
            if (!connected) {
                ToastUtils.showShort("请检查您的网络");
                return null;
            }
        }
        return joinPoint.proceed();
    }
}

3、使用很简单,如获取短信验证码的方法,直接在上面加上@CheckNet注解,即可在发送请求前先判断手机网络。如果没网,会提示"请检查您的网络",而不走方法内逻辑。:

@CheckNet
public void getCheckCode(String number) {
    //doSomething...
}

4、反编译看下里面的魔法
该框架在编译时自动生成相关代码,并不会有效率上的问题,我们可以反编译看下.class文件:

  private static final Object getCheckcode_aroundBody1$advice(LoginPresenter paramLoginPresenter, String paramString, JoinPoint paramJoinPoint, CheckNetAspect paramCheckNetAspect, ProceedingJoinPoint paramProceedingJoinPoint)
  {
    if (((CheckNet)((MethodSignature)paramProceedingJoinPoint.getSignature()).getMethod().getAnnotation(CheckNet.class) != null) && (!NetworkUtils.isConnected()))
    {
      ToastUtils.showShort("请检查您的网络");
      return null;
    }
    getCheckcode_aroundBody0(paramLoginPresenter, paramString, paramProceedingJoinPoint);
    return null;
  }

  private static final void getCheckcode_aroundBody0(LoginPresenter paramLoginPresenter, String paramString, JoinPoint paramJoinPoint)
  {
    //doSomething...
  }

  @CheckNet
  public void getCheckcode(String paramString)
  {
    JoinPoint localJoinPoint = Factory.makeJP(ajc$tjp_0, this, this, paramString);
    getCheckcode_aroundBody1$advice(this, paramString, localJoinPoint, CheckNetAspect.aspectOf(), (ProceedingJoinPoint)localJoinPoint);
  }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • 团队开发框架实战—面向切面的编程 AOP 引言 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统...
    Bobby0322阅读 4,145评论 4 49
  • 精英都是出之精英家庭吗?其实我也是很赞同的,但是绝非绝对,如果真是这样,那人或者就没有意义了。出生在精英家庭固然更...
    suxiliu阅读 191评论 0 0
  • 小狐狸花背是一只小雌狐,一身非常漂亮闪着红色光泽的毛皮!灵活的眼睛,显得很妩媚!她的背上却有一道很惹眼的伤痕,触目...
    梦貘阅读 8,470评论 0 2
  • 8.商业是最大的慈善
    尘世书童阅读 116评论 0 0