如何提高安卓代码质量

Why

代码也是一种产品,没人希望使用劣质产品。
高质量的代码,正确,高效,清晰,可靠。
作为码农,我们的工作应该不仅仅是写代码,而是要写高质量的代码。

How

遵循语言规范

所有语言都有官方的或者大公司出品的规范文档。Java和Kotlin也不例外。
当然代码规范文档很多时候显得复杂而冗长,不利于记忆,这个时候就要利用现代IDE的力量。
以Android Studio为例,本身就可以在config/codestyles里面放自己想遵循的代码规范,或者可以使用Checkstyle插件(当然用gradle也行,不过我更喜欢插件的形式)。
光有代码检查,手动改代码的话太累,能不能也自定义代码格式化呢?
我目前还没发现能让检查代码和格式化代码使用同一个XML文件的方法。我的做法是使用另一个插件: Google java format。这个插件可以选择普通的java规范或者AOSP规范。
当然,并不是说format一下就万事大吉了,很多地方还是需要手动解决。不过至少不再为导入排列为字典序这种事情费神了。
Kotlin的话,目前还没有类似的插件,不过应该也只是时间问题。大体上遵循和Java一样的风格即可。

静态语言分析

这个是比基本语言规范更进一步的分析。格式规范的代码完全可能是有问题的,静态语言分析能帮我们找出潜在的问题。自带的有Android Lint,可以通过插件很方便地使用的有FindBugs,当然还是可以通过gradle来集成。至于PMD,貌似AS的插件库里面搜不到,而且对其规则有所争议。因此就我而言的话,FindBugs已经够了。

崩溃分析平台

另一个至关重要的部分就是处理和报告崩溃。同样很多种方法可供选择,自己发送错误报告到自己的服务器,或者使用一些现成的免费或者付费平台。我选择的是Twitter出品的Fabric。

测试

安卓测试分为单元测试和UI测试,一般就用JUnit,Mockito还有Espresso。写测试用例很花时间,不过如果改动不大的话,就是定海神针,做改动重构什么的心里有底。当然一天一个样的还是算了。

盲区

有一些bug以上方法都查不出来,最终还是会出现在崩溃平台上。
这时候应该高度重视这些bug,分析其出现的原因:
是写代码的时候没考虑到吗?
是某次改动/变化留下的后遗症吗?
总而言之,修复bug是最基本的,还要挖掘背后隐藏的问题。尤其是自身原因导致的问题,比如思维不周,粗心大意等等,找个小本子记着,千万别再犯。

安卓SDK

做安卓开发,首先就得最大程度地发挥安卓SDK。
比如我就是到很后面才发现,TextUtils里面居然还提供了null safe的equals方法。
所以没事多翻翻官方文档。更进一步的就是去读源码,不过这是一个大坑,毕竟就连这些库都只是Framework层的一部分,以后再说。

第三方库

第三方库良莠不齐,在导入到项目中之前需要认真考虑:

  • 我真的需要这个库吗?
  • 这个库的评价如何?看看有多少颗星星。
  • 这个库稳定性如何?看看issue未处理个数以及上一次更新时间。

总体来说,第三方库是安卓开发者的一大助力。很多优秀的第三方库如Rxjava,Okhttp,Glide等等早已成为标杆。
只是在导入之前一定要谨慎,然后最好再加一层封装,日后决定变更的时候方便。因为安卓对于包大小很敏感,一两个库可能没什么,几十个下来区别还是挺大的。另外低质量的库会带来很多麻烦,比如意料之外的崩溃,没有按照期望工作等等。
有些时候,我们需要修改库的源码。但这也导致新的问题。首先是需要保证修改是正确的,其次就是以jar包的形式导入不利于库的更新。
总而言之,使用优秀的第三方库,对于质量存疑的第三方库持谨慎态度。

避免重复

有时候重复是无可避免的,比如我们每天都要吃饭睡觉。
不过就代码而言,我们希望重复的时候能轻松点,比如重复一行代码而不是几百行。
把常用的代码片段封装成类和函数。到一定程度,你会发现这已经是一个库的雏形了。
此外,安卓里面的基类和接口也是重要的避免重复的手段。将大量通用的逻辑封装到基类和接口里面,代码会清晰简洁很多。

IDE插件

IDE插件可以帮我们省很多事情。比如Butterknife自动绑定view,比如自动转Parcelable等等。你不希望在枯燥的重复上浪费时间。这样就有更多的时间来集中写好核心代码。

算法和数据结构

在平常工作中,问题不像刷题那样有明确的答案,很多都是trade-off。
因此,我们能做的就是平时尽量增加算法和数据结构的知识储备,然后在需要的时候能拿出来。
对于安卓平台,速度和内存都很重要,某些时候内存甚至更重要一些。
设计功能的时候就应当考虑到数据量的问题,尽量不要在移动端来处理和计算大型数据。
当需要在移动端使用复杂的算法或者数据结构的时候,往往说明设计有问题。毕竟后端可以代为处理,前端还是轻量化的为好。

设计模式

设计模式的层次比算法和数据结构更高。多了解一下设计模式,对写代码也是很有帮助的。
设计模式看起来很多种,安卓里面需要常用的往往也就几种,单例,工厂,建造。
需要知道的是,设计模式通常是以增加文件数量为代价的,如果需求不是完美契合,还是不要生搬硬套为好。

架构

架构又高了一层。和算法和数据结构、设计模式类似,我们以学习参考为主,当然你要是能自己设计架构,我服。
安卓的话可以参考谷歌的Github官方架构范例,之前是MVP,MVVM,Clean,现在比较新的是Component。
架构最好是一开始就选择好,后面再来改,基本上就是重写一遍App了。
同样架构也有trade-off。层次划分的越多,代码就越细,开发、合作、测试就越简单,但是相对应的,文件数量就越多。这个“多”往往是成倍增长。
因此在开发App前,最好对App有个大致的估计,根据其期望的复杂度来选择架构比较科学。

永远在追求完美的路上

完美永不可得。就算得到了,改变和发展也会破坏掉这份完美。
尽管如此,还是要追求完美。
写新代码,争取一步到位。可以写的稍微慢一点,但不要抱“以后再改”的想法。
改旧代码,动手之前一定要想清楚会影响到其他哪些地方,虽然测试能验证一些基本的功能,但有些潜在的bug就算是测试也很难测出来。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 141,625评论 20 608
  • 9月17日,2016年中秋节的最后一天,北马如约而至。 虽然是第二次跑全马,没有了去年首马的紧张和兴奋,但潜意识还...
    汉马帮阅读 355评论 2 5
  • 去姥姥家拍的一组有感觉的照片,配以无色调的黑白色,模糊的年代感,慵懒的色调。
    传奇小黑猫阅读 50评论 0 4
  • 感觉到没有?我度过了一个愉快的下午。速写:山村记忆。
    曾颖阅读 48评论 0 4
  • 后来快五点的时候我让郑轩再睡一会,他头也不抬的说我的表情仿佛要在他睡着的时候杀掉他的样子,所以坚决不睡。 …… 我...
    殴打屁屁的安打打阅读 31评论 0 0