IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android AOP切面编程之:AspectJ (三)字节码分析和应用场景 -> 正文阅读

[移动开发]Android AOP切面编程之:AspectJ (三)字节码分析和应用场景

1:Android AspectJ 插件集成

1.1:AspectJ版本和 Gradle以及Gradle Tools 版本对应关系

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

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-14 10:04:13  更:2022-05-14 10:05:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:33:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码