cotlin java go_Aspectj 在Android中的简单使用(Java + Kotlin)-Go语言中文社区
OOP&AOP
OOP(Object Oriented Programming):面向对象编程。把问题或功能模块化,每个模块处理自己的事。
AOP(Aspect Oriented Programming):面向切面编程。把分散于不同模块中的相同业务放到统一的地方来管理。如:日志记录,业务埋点,持久化,性能监控,数据校验,缓存,权限检查,异常处理等。
AspectJ简介
AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件,在编译期注入代码。代表框架:Hugo(Jake Wharton)
基本概念
Join Points:连接点,程序中可切入的点。如:方法调用时,读取某个变量时
Pointcut:切入点,代码注入的位置,其实就是有条件限定的Join Point,例如只在特定方法中注入代码
Aspect:切面,一个关注点的模块化
Advice:在切入点注入的代码,一般有before、after、around三种类型
Target Object:被一个或多个aspect横切拦截操作的目标对象
Weaving:把Advice代码织入到目标对象的过程
Inter-type declarations:用来个一个类型声明额外的方法或属性
Demo示例
给方法添加性能测试
Java版本
1.添加依赖
Project->bulid.gradle
dependencies {
...
classpath 'org.aspectj:aspectjtools:1.8.13'
classpath 'org.aspectj:aspectjweaver:1.8.13'
}
Module->build.gradle
dependencies {
...
implementation 'org.aspectj:aspectjrt:1.8.13'
}
// 最后面添加即可
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
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.5",
"-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
}
}
}
}
2.自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PerformanceAnnotation {
String value();
}
3.自定义切面
@Aspect
public class PerformanceAspect {
public static final String TAG = PerformanceAspect.class.getSimpleName();
@Pointcut("execution(@ com.tongjin.aspectj.java.PerformanceAnnotation * *(..))")
public void performancePointcut(){}
@Around("performancePointcut()")
public Object wavePerformancePointcut(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 类名
String className = methodSignature.getDeclaringType().getSimpleName();
// 方法名
String methodName = methodSignature.getName();
// 功能名
PerformanceAnnotation behaviorTrace = methodSignature.getMethod().getAnnotation(PerformanceAnnotation.class);
String value = behaviorTrace.value();
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - start;
Log.e(TAG, String.format("%s类中%s方法执行%s功能,耗时:%dms", className, methodName, value, duration));
return result;
}
}
4.使用
@PerformanceAnnotation("performance")
public void clickMe(View view) {
Toast.makeText(this, "Click", Toast.LENGTH_SHORT).show();
}
5.日志输出
Kotlin版本
由于java版本添加依赖的方式,在kotlin中不起作用,采用大神方案
1.添加依赖
Project->build.gradle
dependencies {
...
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4'
}
Module->bulid.gradle
apply plugin: 'android-aspectjx'
2.自定义注解
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class PerformanceAnnotation(val value: String)
3.自定义切面
@Aspect
class PerformanceAspect {
companion object {
val TAG = PerformanceAspect::class.java.simpleName
}
@Pointcut("execution(@ com.tongjin.myapplication.PerformanceAnnotation * *(..))")
fun performancePointcut() {
}
@Around("performancePointcut()")
@Throws(Throwable::class)
fun wavePerformancePointcut(joinPoint: ProceedingJoinPoint) {
val methodSignature = joinPoint.signature as MethodSignature
// 类名
val className = methodSignature.declaringType.simpleName
// 方法名
val methodName = methodSignature.name
// 功能名
val behaviorTrace = methodSignature.method.getAnnotation(PerformanceAnnotation::class.java)
val value = behaviorTrace.value
val start = System.currentTimeMillis()
joinPoint.proceed()
val duration = System.currentTimeMillis() - start
Log.e(TAG, "${className}类中${methodName}方法执行${value}功能,耗时:${duration}ms")
}
}
4.使用
@PerformanceAnnotation("performance")
fun clickMe(view: View) {
Toast.makeText(this, "Click", Toast.LENGTH_SHORT).show()
}
5.日志输出
cotlin java go_Aspectj 在Android中的简单使用(Java + Kotlin)-Go语言中文社区相关推荐
- rust的矿坑_转: Rust中的Pin详解 【Rust语言中文社区】
Rust中的Pin详解 原创 automanyang Rust语言中文社区 昨天 https://mp.weixin.qq.com/s/PjctbPbyR5OeaqTHZdB5uQ 相关概念 Pin ...
- android studio添加繁体,Android (Android studio3.0.1)一篇可以实现app多语言的转换(简单操作)的教程-Go语言中文社区...
最近接触到了项目需要,多语言的转换.网上有很多资料,我整理一些,简单适合自己使用的操作. 第一步:打开Android studio 添加 Android Studio插件:AndroidLocaliz ...
- java 航班_Java实现简单航班查询系统-Go语言中文社区
#java实现简单航班管理系统 题目要求:声明一个Flight(航班)类,该类包含private域航班号(如:CA1430),起飞时间(如:10:15AM),到达时间(如:2:30PM).为该类声明合 ...
- java黄金连分数_蓝桥杯 | Java B组省赛真题练习——黄金连分数-Go语言中文社区...
标题: 黄金连分数 黄金分割数0.61803... 是个无理数,这个常数十分重要,在许多工程问题中会出现.有时需要把这个数字求得很精确. 对于某些 精密工程,常数的精度很重要.也许你听说过哈勃太空望远 ...
- linux apk 拆分 odex,android apk反编译和odex转dex-Go语言中文社区
http://www.cnblogs.com/wanqieddy/archive/2012/03/01/2375424.html 大家好,这里介绍apk反编译操作. 1:apk反编译 2:odex转d ...
- android 开发tv盒子,一步一步学习Android TV/盒子开发(二)-Go语言中文社区
TV.机顶盒开发调试不能像手机一样通过USB线连接调试,可通过ADB连接调试 连接电视 adb connect 10.74.84.199 连接后就可以开始开发调试了! 断开连接 // 断开某个设备 a ...
- 基于python爬虫的论文标题_python爬虫——简单论文标题检索-Go语言中文社区
有趣的爬虫,独有的意义召唤着我去学习,去尝试.最近有感于每天对于论文的收集,感觉自己的收集速度赶不上论文的更新速度,同时对于自己想找到的论文的收集比较麻烦.因此,学习用python写一个很简单的爬虫, ...
- java以太坊源码分析_以太坊区块链Java(EthereumJ)学习笔记:区块链结构-Go语言中文社区...
本文对EthereumJ的区块链相关的代码做一个简单的介绍. 以太坊区块链 以太坊区块链是在Bitcoin区块链的基础上发展起来的.区块链的数据结构既保留了Bitcoin区块链验证数据的真实性和完整性 ...
- node如何输出html页面,【自己的整理】node.js直接输出一个非常简单的HTML页面-Go语言中文社区...
刚开始接触nodejs,先记录一下最开始用node输出一个很简单的界面 在远程服务器上先创建一个js文件 helloworld.js [root@towrabbit nodejsLearn]# vi ...
最新文章
- ”计算机操作系统“学习笔记1
- 利用GNU的parted进行分区
- 世界32条谣言,你被骗了多少?
- 数据库连接python_python连接数据库
- 解决canvas画图模糊的问题
- c#事务的使用、示例及注意事项
- x230无线网卡驱动服务器版,ThinkPad X230网卡驱动
- android layout 渲染,java – 渲染android.support.design.widget.CoordinatorLayout的问题
- 基于matlab的瑞利衰落信道建模和仿真
- python快速搭建服务器方法
- 2019寒假专题一 L CodeForces - 1260B
- 谷歌浏览器配置微信浏览器_在 Chrome (谷歌浏览器) 中模拟微信内置浏览器
- html5以图片为背景的代码,HTML5画布背景图片
- 最小公倍数C语言怎么算,算法:最大公约数和最小公倍数(C语言表示)
- ‘Converting circular structure to JSON‘报错的解决方案
- 电子科技大学硕士毕业论文和博士毕业论文Latex模板及问题集锦
- Python 数据分析微专业课程--项目06 城市餐饮店铺选址分析
- 数智化时代,驱动企业转型升级的“三驾马车”是什么?
- 流媒体服务器——Licode Janus-gateway Mediasoup Medooze 分析
- java模拟回合制游戏大小姐_[源码和文档分享]基于java的RPG回合制游戏
热门文章
- mui框架 页面无法滚动解决方法
- clickhouse 复杂查询时嵌套连接join可能存在的异常解决(xjl456852原创)
- System.UriFormatException: Invalid URI 解决方法
- mysql运维技巧_​mysql初级运维使用技巧
- TikTok如何将粉丝转到私域,提高转化和复购?
- 跨境电商和独立站哪个好?
- Google浏览器一开启就提示“请停用以开发者模式运行的扩展程序“解决方案
- Leetcode每日一题:345.reverse-vowels-of-a-string(反转字符串中的元音字母)
- Leetcode:8.string-to-integer-atoi(字符串转整数)
- 对文件夹内所有文件批量命名