参考:
深入理解Android之AOP
导包
我使用的是gradle_plugin_android_aspectjx
Github:https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx
1.在项目的build.gradle中引用插件classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8'
,
2.在需要依赖的module中引入aspectj
依赖(当前以默认的app module)为例
这样就完成了基础的导包
使用例子
1.检查网络
1.首先定义一个CheckNet
的注解
package com.fangju.aspectjsample;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by FangJu on 2020/3/22.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckNet {
}
2.然后定义一个切面处理类CheckNetAspect
package com.fangju.aspectjsample;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.view.View;
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;
import org.aspectj.lang.reflect.MethodSignature;
import androidx.fragment.app.Fragment;
/**
* Created by FangJu on 2020/3/22.
*/
@Aspect
public class CheckNetAspect {
// 找到处理的切点
@Pointcut("execution(@com.fangju.aspectjsample.CheckNet * *(..))")
public void checkNetBehavior() {
}
// 处理切面
@Around("checkNetBehavior()")
public Object checkNet(ProceedingJoinPoint point) throws Throwable {
// 获取CheckNet注解
MethodSignature signature = (MethodSignature) point.getSignature();
CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);
if (checkNet != null) {
// 判断有没有网络
Object object = point.getThis();// 当前切点所在类
Context context = getContext(object);
if (context != null) {
if (!isNetworkAvailable(context)) {
Toast.makeText(context, "网络未连接", Toast.LENGTH_SHORT).show();
return null;
}
}
}
return point.proceed();
}
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 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.length > 0) {
for (NetworkInfo info : networkInfo) {
// 判断当前网络状态是否为连接状态
if (info.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
}
测试:
这样会先执行CheckNetAspect#checkNet
中的代码,然后再处理start方法中的代码
2.防止重复点击
package com.fangju.aspectjsample;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by FangJu on 2020/3/22.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AopClick {
}
package com.fangju.aspectjsample;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
/**
* Created by FangJu on 2020/3/22.
*/
@Aspect
public class OnClickAspect {
private static final long BASE_TIME = 2000L;
private long lastClickTime;
@Pointcut("execution(@com.fangju.aspectjsample.AopClick * *(..))")
public void onClickBehavior() {
}
@Around("onClickBehavior()")
public Object onClick(ProceedingJoinPoint point) throws Throwable {
long clickTime = System.currentTimeMillis();
MethodSignature signature = (MethodSignature) point.getSignature();
AopClick aopClick = signature.getMethod().getAnnotation(AopClick.class);
if (aopClick != null) {
if (clickTime - lastClickTime >= BASE_TIME) {
lastClickTime = clickTime;
return point.proceed();
}
}
return null;
}
}
测试: