Android 中AOP编程

一般我们判断是否有网络跳转时,这样写

  /**
  * 跳转到待收货页面
  */
 public void toSecond() {
    // 判断当前有没有网络
    if(CheckNetUtil.isNetwork(this)) {
        // 当前有网络我才跳转
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
     }
    }

学习了AOP之后我只需这样写

@CheckNet
public void toSecond() {
    Intent intent = new Intent(this, SecondActivity.class);
    startActivity(intent);
}

看着代码少了好多,而且方便管理,还可以根据不同需求修改没网络的提示。是不是很牛逼,这是要感谢
红橙Darren大神,最近一直在跟着他学习。
好了,看一下实现

1.百度下载安装AspectJ ,都是下一步。

2.项目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()
 }

dependencies{}上添加:

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

3.AspectJ 安装目录下拷贝aspectjrt.jar包,导入工程

4.标记切点,创建CheckNet

 @Target(ElementType.METHOD)  
 @Retention(RetentionPolicy.RUNTIME)
 public @interface CheckNet {
 }
Target参数含义:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解。
TYPE:类、接口或枚举声明。
FIELD:字段声明
METHOD:方法的声明
PARAMETER:参数声明
CONSTRUCTOR:构造函数的声明
LOCAL_VARIABLE:本地变量声明
ANNOTATION_TYPE:注释类型声明
PACKAGE:包声明
Android 中AOP编程_第1张图片
Paste_Image.png

Retention(RetentionPolicy.RUNTIME)

  RUNTIME 运行时 
  CLASS 代表编译时期 
  SOURCE 代表资源
Android 中AOP编程_第2张图片
Paste_Image.png

5.创建SectionAspect

@Aspect
public class SectionAspect {

 /**
  * 找到处理的切点
  * * *(..)  可以处理所有的方法
  */
 @Pointcut("execution(@com.projectdemo.zwz.httputils.checknet.CheckNet * *(..))")
 public void checkNetBehavior() {
 }
/**
 * 处理切面
 */
@Around("checkNetBehavior()")
public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable {
    Log.e("TAG", "checkNet");
    // 网络检测
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);
    if (checkNet != null) {
        // 2.判断有没有网络  怎么样获取 context?
        Object object = joinPoint.getThis();// View Activity Fragment ; getThis() 当前切点方法所在的类
        Context context = getContext(object);
        if (context != null) {
            if (!isNetworkAvailable(context)) {
                // 3.没有网络不要往下执行
                Toast.makeText(context, "请检查您的网络", Toast.LENGTH_LONG).show();
                return null;
            }
        }
    }
    return joinPoint.proceed();
}
/**
 * 通过对象获取上下文
 *
 * @param object
 * @return
 */
private Context getContext(Object object) {
    if (object instanceof Activity) {
        return (Activity) object;
    } else if (object instanceof Fragment) {
        Fragment fragment = (Fragment) object;
        return fragment.getActivity();
    } else if (object instanceof View) {
        View view = (View) object;
        return view.getContext();
    }
    return null;
}

/**
 * 检查当前网络是否可用
 *
 * @return
 */
private static boolean isNetworkAvailable(Context context) {
    // 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
    ConnectivityManager connectivityManager = (ConnectivityManager)
            context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        // 获取NetworkInfo对象
        NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();

        if (networkInfo != null && networkInfo.length > 0) {
            for (int i = 0; i < networkInfo.length; i++) {
                // 判断当前网络状态是否为连接状态
                if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
              }
          }
      }
       return false;
   }
    }

6.使用

 @CheckNet
 public void toSecond() {
    Intent intent = new Intent(this, SecondActivity.class);
    startActivity(intent);
 }

你可能感兴趣的:(Android 中AOP编程)