Android 代码优化工作经验总结

总结在三星工作期间做过的一些代码优化工作

Posted by SnowCrane on 2019-10-14

Code review Summary

Lint

android 官方关于Lint的说明:link

Lint first look

Correctness:不够完美的编码,比如硬编码,使用过时的API等
Performance:对于性能有影响的编码,比如:静态引用,循环引用等
Internationalization:国际化,直接使用汉字,没有使用资源引用等
Sercurity:不安全的编码,比如在Webview中允许使用 JavaScriptInterface等
Usability:可用的,有更好的替换的,比如排版、图标格式建议、png格式等等
Accessibility:辅助选项,比如ImageView的ContentDescription往往建议在属性中定义等

常见的检查问题列表:(参考网址:http://tools.android.com/tips/lint-checks)

  1. Correctness
    1. DuplicatedIds
      Layout中id应该唯一
    2. NewApi
      代码中使用的某些API高于Manifest中的Min SDK
    3. InconsistentArrays
      字符串国际化中,同一名字的的String-Array对应的item值不相同
    4. Registered
      Activity/Service/ContentProvider没有通过AndroidManifest注册
    5. Deprecated
      使用已经废弃的API
    6. PxUsage
      避免使用px,使用dp
  2. Correctness:Messeges
    1. MissingTranslation 字符串国际化不完全
    2. ExtraTranslation 国际化的字符串,在默认位置 (defaultlocale),没有定义
  3. Security
    1. SetJavaScriptEnabled
      不确定你的程序中确实需要JavaScript就不要执行 SetJavaScriptEnabled。
      2)ExportedContentProvider/ExportedReceiver/ExportedService/ExportedActivity
      ContentProvider/Receiver/Service/Activity的exported为true时,设置一个Permission,让使用者获取了Permission才能使用。
    2. HardcodedDebugMode
      不要在manifest中设置android:debuggable。
      设置它,编译的任何版本都要采用指定的debug模式。不设置,编译Eng版本采用debug模式;编译User版本采用release模式。
  4. Performance
    1. DrawAllocation
      避免在绘制或者解析布局(draw/layout)时分配对象。E.g.,Ondraw()中实例化Paint对象。
    2. ObsoleteLayoutParam
      Layout中无用的参数。
    3. UseCompoundDrawables
      可优化的布局:如包含一个Imageview和一个TextView的线性布局,可被采用CompoundDrawable的TextView代替。
    4. UseSparseArrays
      尽量用Android的SparseArray代替Hashmap
    5. DisableBaselineAlignment
      如果LinearLayout被用于嵌套的layout空间计算,它的android:baselineAligned属性应该设置成false,以加速layout计算。
    6. FloatMath
      使用FloatMath代替Math。
    7. NestedWeights
      避免嵌套weight,那将拖累执行效率
    8. UnusedResources/UnusedIds
      未被使用的资源会是程序变大,并且编译速度降低。
    9. Overdraw
      如果为RootView指定一个背景Drawable,会先用Theme的背景绘制一遍,然后才用指定的背景,这就是所谓的“Overdraw”。
      可以设置theme的background为null来避免。
    10. UselessLeaf/UselessParent
      View或view的父亲没有用
  5. Usability:Typography
    1. TypographyDashes
      特殊字符需用编码代替:“–”需要用“–”;“—”需要用“—”
    2. TypographyEllipsis
      特殊字符需用编码代替:“…”需要用“…”
    3. TypographyOther
      问题:“©”需要用“©”
  6. Usability:Icons
    1. IconNoDpi
      Icon在nodpi和指定dpi的目录下都出现。
    2. GifUsage
      Image不要用GIF,最好用PNG,可以用JPG。
  7. Usability
    1. BackButton
      Android中不要设计有Back的按钮,Android中一般有Back的硬按键。
    2. ButtonCase
      Button的“Ok”/“Cancel”显示大小写一定,不要全大写或全小写。有标准的资源的字符串,不要自己再定义,而要用系统定义的: @android:string/ok和@android:string/cancel
  8. Accessibility
    1. ContentDescription
      ImageView和ImageButton应该提供contentDescription
  9. Internationalization
    1. HardcodeText
      硬编码的字符串应该在资源里定义
    2. EnforceUTF8
      所有XML资源文件都应该以UTF-8编码

Lint可以识别的问题,主要包括:
1)布局性能(以前是layoutopt工具,可以解决无用布局、嵌套太多、布局太多)
2)未使用到的资源
3)不一致的数组大小
4)国际化问题(硬编码)
5)图标的问题(重复的图标,错误的大小)
6)可用性问题(如不指定的文本字段的输入型)
7)manifest文件的错误

重点关注以下部分:
Lint demo

另外一张比较有价值的图:(图片是之前从CSDN上面存储的,就不放水印中的连接了)

Lint pic

代码分析工具整理:

Lint pic

Profile GPU Rendering in setting

打开手机里面的开发者选项,选择Profile GPU Rendering,选中On screen as bars的选项。

GPU Rendering 1

选择了这样以后,我们可以在手机画面上看到丰富的GPU绘制图形信息,分别关于StatusBar,NavBar,激活的程序Activity区域的GPU Rending信息。

GPU Rendering 1

随着界面的刷新,界面上会滚动显示垂直的柱状图来表示每帧画面所需要渲染的时间,柱状图越高表示花费的渲染时间越长。

GPU Rendering 1

中间有一根绿色的横线,代表16ms,我们需要确保每一帧花费的总时间都低于这条横线,这样才能够避免出现卡顿的问题。

GPU Rendering 1

每一条柱状线都包含三部分,蓝色代表测量绘制Display List的时间,红色代表OpenGL渲染Display List所需要的时间,黄色代表CPU等待GPU处理的时间。

Prevent问题类型

性能:

内存泄漏
定制的内存和网络资源泄漏
数据库连接泄漏

导致崩溃的缺陷 :

空指针引用
释放后引用
多次释放
不正确的内存分配
不匹配的数组新建/删除

不正确的程序行为:

逻辑错误导致的死代码
未初始化变量
负数的无效引用

并发:

死锁 
错误使用的阻塞调用

不正确的APIs使用:

STL使用错误
API错误处理
安全性问题

安全编码缺陷 :

缓冲区溢出
整形溢出  
缺失的/ 不充分的恶意数据和字符串输入的验证
格式化字符串的不安全
SQL注入攻击
交叉站点脚本攻击

隐含的缺陷 :

整个系统折衷
服务拒绝攻击
优先权扩张
保密数据泄漏
数据丢失
仲裁代码执行