前两篇文章已经很好的说明了AOP的使用方式,但是话说回来了,在项目中有什么卵用?能帮到我平时开发吗?
其实我就喜欢这么直接的朋友,其实一开始的时候我也是这么觉得的!我花了这么长时间学习这个东西到底有什么卵用?但是后来我渐渐的发现这个东西还是挺有用的,平时能帮助到我们节省很多代码的!好了,废话不多说直接说说这个东西在项目中到底有什么卵用!!!
一张复仇者联盟镇楼(感兴趣的我可以发你)!皮一下就是这么开森。。。
AspectJ在项目中的卵用
- 解决一些判断条件登录的问题;
- 解决一些埋点的问题;
- 还有些就有待于发现了...
1. 解决一些判断条件登录的问题
不知道大家在项目中有没有这样的需求?APP有些内容是需要登录才能继续向下走的,这个时候你需要先判断用户是否登录,然后再能往下走,这个需求很常见。但是如果有了AOP这个框架的话,再也不用if/else了,也不用在每一地方都if/else了。
好了,实现的效果说完了,那么我们开始装逼吧!!!
对于这个需求,如果之前你看了上两篇文章的话,那么这个需求就可以说是so easy了,我们看看怎么实现的吧!
1.1 首先你需要一个注解,是长这样的!
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CheckLogin {
}
复制代码
这就是一个注释在方法上的注解!!!仅此而已。。。
1.2 写相应的切面方法。
先来看下代码,然后我们在讲解
@Aspect
public class LoginAspect {
private static final String TAG = LoginAspect.class.getSimpleName();
@Around("execution(@com.jinlong.aspectjdemo.CheckLogin * *(..))")
public Object beforeDebugTraceMethod(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log.e(TAG, "beforeDebugTraceMethod: " + method.toString());
//获取上下文的方法
Context context = (Context) joinPoint.getThis();
if (APP.isIsLogin()) {
return joinPoint.proceed();
} else {
Intent intent = new Intent(context, MainActivity.class);
context.startActivity(intent);
return null;
}
}
}
复制代码
说明几点问题:
- 通配符:这个我不讲了,上一篇博客已经讲解了,如果有什么不理解的,可以看看AOP埋点从入门到放弃(二) 这篇文章!
- 其实我主要想说的就是里面的这些判断的代码**Context context = (Context) joinPoint.getThis();**其实这里返回的是当前执行的对象,有可能是空的,因为我是在Activity中执行的点击时间,所以这里强转成上下文是没问题的,但是如果你要是写在Fragment的话,就要在获取一下了!
- 这里其实是可以传递相应的数据的,但是只能是相应的基本的数据方式String、int 等;怎么传递呢?这个就涉及到注解的问题了,所以这里只贴出相应的代码了,不再本文的讲解中!!!
首先注解编程这个样子了:就是添加了一个相应传递的值。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CheckLoginDefault {
String param1() default "";
}
复制代码
然后看怎么获取?
@Around("execution(@com.jinlong.aspectjdemo.CheckLoginDefault * *(..))")
public void beforeDebugCheckLogin(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
CheckLoginDefault annotation = method.getAnnotation(CheckLoginDefault.class);
Log.e(TAG, "注解传递的值为:" + annotation.param1());
Context context = (Context) joinPoint.getThis();
Toast.makeText(context, "注解传递的值为\n" + annotation.param1(), Toast.LENGTH_SHORT).show();
}
复制代码
里面注解传递的值为:Log打印出来的值。这里由于没有执行之前方法的内容,所以不会打印前面方法的Toast了!
最后看看怎么用?
@CheckLoginDefault(param1 = "token")
public void checkLoginDefault(View view) {
Toast.makeText(this, "执行下一步操作", Toast.LENGTH_SHORT).show();
}
复制代码
通过param1添加相应的参数就可以了,这样你就可以在点击的时候进行相应的处理了!!!
2. 解决项目中的埋点问题
首先确定好一个问题,你们项目埋点要埋些什么东西?比如点击事件,或者方法的执行时间?这些都是比较简单的内容,但是如果你要在某个点击事件的时候,还想获取相应的内容,这个时候就比较复杂了,怎么说呢?因为注解只能传递相应的基本类型参数(也可能是我自己的只是层面有限),所以这里存在一定的问题?什么样的问题呢?埋点的时候,怎么区分这些类型,只有在你传的时候区分了,添加注解的时候去区分,就没有然后了。至于其他的一些内容,看你们产品需要什么,需要什么埋什么! 这里就直接上两个简单的例子吧!
2.1 相应方法的埋点
@Before("execution(* android.app.Activity.on*(..))")
public void onActivityMethodBefore(JoinPoint joinPoint) {
String key = joinPoint.getSignature().toString();
Log.e(TAG, "onActivityMethodBefore: 切面的点执行了!" + key);
}
复制代码
2.2 相应方法的执行时间
@Around("call(* com.jinlong.aspectjdemo.MainActivity.callMethod(..))")
public void aroundCallMethod(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
joinPoint.proceed();
long endTime = System.currentTimeMillis();
Log.e(TAG, "方法执行的时间为" + (endTime - startTime));
}
复制代码
这里就不详细讲解了!细节前面都讲了。至于埋点东西多的话,可以参照上面那个传递参数的,总之怎么简单怎么来!!!
除了AOP实现6.0以上权限的内容,基本上项目中就这些使用的地方,因为最近公司开了一个新项目,所以比较忙,没有时间去看关于权限的问题!其实关于AOP实现6.0以上权限的内容,很多的内容都要讲,估计没有时间细看,所以等忙完这个项目后,我会仔细看一下给伙伴们讲,如果现在讲的话,怕有些地方讲错了,对不起广大小伙伴!!!