GitHub - HujiangTechnology/gradle_plugin_android_aspectjx: A Android gradle plugin that effects AspectJ on Android project and can hook methods in Kotlin, aar and jar file.
2:AspectJ 语法解析AspectJ 其实是一种 AOP框架,AOP是实现程序功能统一维护的一种技术,利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各部分之间的耦合性降低,提高程序的可重用性,提高开发效率。
2.1: 切点切点表示对哪些方法进行拦截,拦截后怎么处理
2.2 :切面(Aspect)类是对物体特征的抽象,切面就是对横切关注点的抽象
2.3:连接点(JoinPoint)JPoint 是程序的关键执行点,也是我们关注的重点。它是指被拦截到的点(如方法、字段、构造器等)
2.4:切入点(PointCut)对 JoinPoint进行拦截的定义,PointCut 的目的是提供一种方法使得开发者能够选择自己感兴趣的 JoinPoint
2.5: 通知(Advice)切入点仅用于捕捉连接点集合,但是除了捕捉连接点集合外其他什么事情都没做,事实上实现横切行为我们需要使用通知,它一般指拦截到 JoinPoint 后需要执行的代码,分为前置,后置,环绕三种类型。
使用 PointCut 对我们指定的连接点进行拦截,通过 Advice ,就可以拦截到 JoinPoint后要执行的代码,Advice 通常有以下三种类型:
1)Before : PointCut 切点之前执行
2)After: PointCut 切点之后执行
3)Around: PointCut 之前,之后分别执行
2.6: call 和 execution区别execution(* android.app.Activity.on**(..))
上述表达式中:execution是一个匹配规则,第一个 * 代表匹配任意方法的返回值,后面语法表示匹配所有 Activity 中以 on开头的 方法,-----》这样我们就可以在 App 中所有 Activity中以 on开头的方法中输出一句log
1) call : 代表调用方法的位置,插入在函数体外面
2)execution: 代表方法执行的位置,插入在函数体内部
3:分析AspectJ插桩字节码 3.1 先看如下插桩AspectJ类源码@Aspect
public class TestAsject {
// 定义切点
@Pointcut("execution(* android.app.Activity+.onCreate(..))")
public void activityOnCreate() {
}
/**
* 环绕增强
* 2022-05-07 16:40:05.714 16885-16885/? I/onCreateInjector: MainActivity: enter
* 2022-05-07 16:40:05.823 16885-16885/? I/onCreate: enter
* @param point
*/
@Around("activityOnCreate()")
public void onCreateInjector(ProceedingJoinPoint point) {
Object object = point.getTarget();
Log.i("TestAsject","onCreateInjector: "+ object.getClass().getSimpleName() + ": enter");
try {
point.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
/**
* 前置增强
* @param joinPoint
*/
@Before("activityOnCreate()")
public void onCreateBefore(JoinPoint joinPoint) {
Log.i("TestAsject", "onCreateBefore: " + joinPoint.getSignature().getDeclaringType() + ":" + joinPoint.getSignature().getDeclaringTypeName());
}
/**
* 后置增强
* @param joinPoint
*/
@After("activityOnCreate()")
public void onCreateAfter(JoinPoint joinPoint) {
Log.i("TestAsject", "onCreateAfter: " + joinPoint.getSignature().getDeclaringType() + ":"
+ joinPoint.getSignature().getDeclaringTypeName());
}
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("TestAsject",": onCreate enter");
}
}
打印内容:
1: 先打印连接点的 环绕通知
2:在打印且连接点的 Before通知
3: 然后打印 连接点的 切点
4:最后打印:连接带你的 After通知
2022-05-12 16:45:49.543 16056-16056/? I/TestAsject: onCreateAround: MainActivity: enter
2022-05-12 16:45:49.543 16056-16056/? I/TestAsject: onCreateBefore: class aop.yhw.com.aspectjproject.MainActivity:aop.yhw.com.aspectjproject.MainActivity
2022-05-12 16:45:49.649 16056-16056/? I/TestAsject: :MainActivity onCreate enter
2022-05-12 16:45:49.649 16056-16056/? I/TestAsject: onCreateAfter: class aop.yhw.com.aspectjproject.MainActivity:aop.yhw.com.aspectjproject.MainActivity
3.2:再看如下插桩AspectJ编译的字节码
4:AspectJ使用场景
4.1 :统计Application中所有方法耗时
@Aspect
public class ApplicationAop {
@Around("call (* com.json.chao.application.BaseApplication.**(..))")
public void getTime(ProceedingJoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
String name = signature.toShortString();
long time = System.currentTimeMillis();
try {
joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
Log.i(TAG, name + " cost" + (System.currentTimeMillis() - time));
}
}
4.2: 对App 中所有的方法进行 Systrace函数插桩
查看应用中方法的耗时与 CPU
情况
@Aspect
public class SystraceTraceAspectj {
private static final String TAG = "SystraceTraceAspectj";
@Before("execution(* **(..))")
public void before(JoinPoint joinPoint) {
TraceCompat.beginSection(joinPoint.getSignature().toString());
}
@After("execution(* **(..))")
public void after() {
TraceCompat.endSection();
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)