首页 存档 技术 查看内容

利用 Annotation 提高 Android 开发的效率

2018-3-30 13:00 |来自: 互联网 361 0

摘要: 今天的主题是 Annotation ,相信大家多多少少都有用过它。 在开始之前先简单的介绍一下自己。 注解能给我们带来很多好处.... 一般来说,注解有两种分类方式 @Target里面的ElementType是用来指定A ...

今天的主题是 Annotation ,相信大家多多少少都有用过它。


在开始之前先简单的介绍一下自己。




注解能给我们带来很多好处....


一般来说,注解有两种分类方式




@Target里面的ElementType是用来指定Annotation类型可以用在哪一些元素上的.


从RetentionPolicy的源码中看出,该枚举有三种类型。



APT是一个命令行工具,它对源代码文件进行检测找出其中的annotation后,使用annotation processors来处理annotation。


自定义一个Processor来编写编译时注解


Processor各个方法的作用


很多第三方库都使用了注解,简化了开发。比如说butterknife,简化了findViewById、setOnClickListener等等,让开发者摆脱一些繁琐的细节,更加关注于业务代码的开发。同时,我们项目中的一些通用组件也可以提取出来。如果能用注解封装的话,那就更加方便了。



自定义一个注解 MyAnnotation,只能作用于方法。

再写一个类AnnotationExample,在某个方法上标注@MyAnnotation


解析类AnnotationExample,通过反射获取testMethod(),并遍历该方法所使用的注解并打印出来。

如果testMethod()@MyAnnotation的话,则打印keyvalue

最终,可以看到打印出来的keyvalue的值


JavaPoet是我比较推荐的一个框架,它是由Square开发的。


这是一个JavaPoet生成一个HelloWorld类的例子,JavaPoet有一套自己的生成规则,大家对此感兴趣的话可以搜一下,也可以看一下我后面分享两个项目的源码,在这里我就不展开了。



下面两篇文章虽然是用Kotlin来实现编译时注解,但是思想是一样,Kotlin的语法不难理解。


build文件夹下能找到编译时注解生成的文件,打开任意一个类,可以看到JavaPoet生成的代码。


一个aspectj的例子,具体用法稍后会提到。


这个类可能有点难理解,在AsyncAspect中用到了Rxjava2Flowable,以后要是有机会的话跟大家可以给大家讲一下Rxjava2


另一个使用aspectj的例子。


在某个方法名前如果标注了@Cache,那就把该方法的返回结果放入缓存中,甚至还可以有缓存的过期时间。



简化版本的ButterKnife,这个库更加轻量级只做了几个最常用的注解,并且它是完全基于Kotlin进行开发的。



整个库包括三个模块:

1injectviewandroid library,包括Injector类和ViewBinder接口。用于在ActivityFragmentViewDialog中进入注入。

2injectview-annotationsjava library,用于存放各个注解,比如@InjectView

3injectview-compilerjava library,使用apt来生成代码


页面路由框架,无论在android还是在iOS的开发中都是很常见的模块与模块之间的解耦工具,特别是对中大型App而言,基本上都会有自己的路由框架。


saf-router:是整个路由框架的核心,可以单独使用。

saf-router-annotation:是路由框架的注解模块,可以基于注解来声明router跳转的页面。

saf-router-compiler:由于我们的注解是编译时注解,而非运行时注解。在程序编译时会生成一个RouterManager的类,此类会管理Approuter mapping信息。


我们sdk中提供了两个注解,简化开发者集成我们sdk的难度。这两个注解都是运行时的,虽然编译时注解效率更高,考虑到集成难度和尽量减少sdk的体积角度,最终还是使用运行时注解。


这是一个注解解析的类,将使用注解的Activity保持到一个map中。



利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。


如果说,面向过程的编程是一维的,那么面向对象的编程就是二维的。OOP从横向上区分出一个个的类,相比过程式增加了一个维度。而面向切面结合面向对象编程是三维的,相比单单的面向对象编程则又增加了方面的维度。


AOP是一种关注点分离的技术。我们软件开发时经常提一个词叫做业务逻辑或者业务功能,我们的代码主要就是实现某种特定的业务逻辑。但是我们往往不能专注于业务逻辑,比如我们写业务逻辑代码的同时,还要写事务管理、缓存、日志等等通用化的功能,而且每个业务功能都要和这些业务功能混在一起,非常非常地痛苦。为了将业务功能的关注点和通用化功能的关注点分离开来,就出现了AOP技术。




告别ThreadHandlerBroadCoast等方式更简单的执行异步方法。只需在目标方法上标注@Async


可以清晰地看到当前的线程和UI线程是不一样的。


基于Spring Cache风格的注解,在 initData() 上标注 @Cacheable 注解和缓存的key。将initData()返回的结果放入缓存中,缓存的keyaddress


在调试时,如果一眼无法看出错误在哪里,那肯定会把一些关键信息打印来。
App 的任何方法上标注 @LogMethod,可以实现刚才的目的。


目前,方法的入参和出参只支持基本类型和String,未来我会加上支持任意对象的打印以及优雅地展现出来。


通常,在 App 的开发过程中会在一些关键的点击事件、按钮、页面上进行埋点,方便数据分析师、产品经理在后台能够查看和分析。


以前在大的电商公司,每次 App 发版之前,都要跟数据分析师一起过一下看看哪些地方需要进行埋点。发版在即,添加代码会非常仓促,还需要安排人手进行测试。而且埋点的代码都很通用,所以产生了 @Hook 这个注解。它可以在调用某个方法之前、以及之后进行hook。可以单独使用也可以跟任何自定义注解配合使用。


先打印method1() is called before initData(),再打印initData(),最后打印method2() is called after initData()


@Prefs 的用法跟之前的 @Cacheable 类似,区别是将结果放到SharedPreferences


一般情况,写下这样的代码肯定会抛出空指针异常,从而导致App Crash

使用 @Safe 可以确保即使遇到异常,也不会导致 App Crash,给 App 带来更好的用户体验。

再看一下logcat的日志,App 并没有 Crash 只是把错误的日志信息打印出来。


无论是开发 App 还是 Service 端,我们经常会用做一些性能方面的测试,比如查看某些方法的耗时。从而方便开发者能够做一些优化的工作。@Trace 就是为这个目的而产生的。
它可以实现追踪某个方法的耗时。如果耗时过长那就需要优化代码,优化完了再进行测试。在生产环境中不建议使用这样的注解。



这个库包含了上面所有的注解操作,我自己开发app时也在用,而且新的使用方法我也会不断地更新。


gradle中,如果apt插件跟aspectj插件一起使用,会报错。

在尝试了Naspectj插件后,终于找到沪江的插件不错,解决了冲突问题。


最后,有问题可以在微信里询问我,也可以关注我的公众号,每周都会定期更新原创的技术文章。目前正在连载Scala学习笔记和Android上的图像框架。



关注【Java与Android技术栈】

更多精彩内容请关注扫码



声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部