Android 中AOP编程
2017-09-29 本文已影响0人
Ayres
一般我们判断是否有网络跳转时,这样写
/**
* 跳转到待收货页面
*/
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:包声明
Paste_Image.png
Retention(RetentionPolicy.RUNTIME)
RUNTIME 运行时
CLASS 代表编译时期
SOURCE 代表资源
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);
}