最近一周做了一些关于Android静态代码检测的东西,对于一些常见的lint警告做了记录,其实对于常见的lint警告我们得处理步骤可以分为如下:
- 查看lint报错的错误类型
- 追踪到代码处,确定是否代码自身问题
- 分析该类错误影响范围
- 确定解决方式(规范代码、添加注解、添加规则)
规范代码
一般是由于开发者在开发时,不细心造成误写等,或者是某些API过时,需要进行手动修改。
添加注解
对于某些特殊需求,可以通过加注解来避免lint报错,以下给出常见的添加注解的地方
java源代码
1 | "xxxx") // xxxx代表某种lint检测类型 ( |
xml
首先添加命名空间
1 | namespace xmlns:tools="http://schemas.android.com/tools" |
然后在报错地方添加
1 | <!--xxxx代表某种lint检测类型,或者可以是直接all,禁止掉所有检测类型--> |
添加规则(lint.xml文件)
对于某些大规模类型的,或者是知道自己必须这么干时,就可以添加规则来规避某种类型的所有lint报错或者是指定路径,亦或者是通过正则指定。
添加规则格式为:
规避一种类型
1 | <!--xxxx代表某种lint检测类型--> |
指定路径
1 | <!--xxxx代表某种lint检测类型--> |
改变lint检测类型
1 | <!--xxxx代表某种lint检测类型--> |
接下来记录下我见到和处理的一些报错类型
1. Missing commit() on SharedPreference editor
缺少commit()方法调用,添加即可;但是你或许会遇到下面这个问题,它依然会lint检测报错:
1 | public void test(){ |
如果是这样的话,建议到指定方法调用处添加注解
@SuppressLint(“CommitPrefEdits”)
2. Use apply() on SharedPreferences
建议使用apply()替换commit(),对于两个方法的区别,建议看看这里
3. Mismatched Styleable/Custom View Name
建议在自定义View的时候,尽量保证View名称与<declare-styleable 的name一致,
若有特殊需求需要对指定进行添加注解.
@SuppressLint(“CustomViewStyleable”)
若存在特殊需求,则更建议在lint.xml中添加规则:
4. Duplicate ids across layouts combined with include tags
在布局中,通过
5. Using android.media.ExifInterface
Avoid using android.media.ExifInterface;use android.support.media.ExifInterface from the support library instead.
使用support包相关替换
6. Hardcoded reference to /sdcard
Do not hardcode “/data/“; use Context.getFilesDir().getPath() instead
lint 给出的修改建议是使用Context.getFilesDir().getPath() 替换直接通过路径拼接,但是根据场景可以自变吧;若不想通过这种方式可以直接忽略,添加注解
类似错误场景:
1 | public class DbCopyHelper { |
@SuppressLint(“ SdCardPath”)
若存在特殊需求,则更建议在lint.xml中添加规则:
7. Attribute unused on older versions
建议添加规则
1 | <!--xxxx代表某个属性--> |
8. Appcompat Custom Widgets
This custom view should extend android.support.v7.widget.AppCompatTextView instead
建议:
1 | 添加规则 |
9. Restricted API
xxx can only be called from within the same library group
方法只能在同一个library group中调用
添加注解:
@SuppressLint(“RestrictedApi”)
或者是规则
10. Invalid format string
在进行字符串格式化处理的时候,需要注意formatted=“false” 的影响
直接添加:
1 | <!--忽略string的format--> |
对于formatted=“false”的理解,在进行string.xml编写的时候,注意内容的占位符号,如果大于等于2个占位符的时候,建议使用formatted=“false”,或者使用正则方式%n$m。
11. Insecure HostnameVerifier
1 | HostnameVerifier hnv = new HostnameVerifier() { |
场景是直接均返回true,被认为是不安全的操作,若知道自己在干什么,可以直接添加注解
@SuppressLint(“AllowAllHostnameVerifier”)
或者添加规则
1 | <!--忽略业务中总是返回true--> |
12. Insecure TLS/SSL trust manager
1 |
|
建议添加规则
1 | <!--忽略信任X509TrustManager带来的危险--> |
13. Obsolete layout params
Invalid layout param in a LinearLayout: layout_centerInParent
建议开发中,对布局的使用注意可用性,在参考代码的时候,注意删除修改后不可用的属性
14. Static Field Leaks
注意在书写单例的时候,避免使用局部context.均转换为全局上下文
15. Node can be replaced by a TextView with compound drawables
这个警告的产生,主要是在一个线性布局中存在一个textView和一个ImageView,认为一个textView可以实现类似的功能,而不用添加多余的嵌套和View;
但是对于特定的需求,不能保证能实现想要的效果,因此建议添加规则忽略:
1 | <!--忽略对linearlayout(包含TextView和ImageView)使用的误报--> |
16. View Holder Candidates
Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling
建议使用ViewHolder
17. Missing baselineAligned attribute
缺少baselineAligned这个属性,建议看看这里,这个警告可以根据需求自行添加属性与否,或者是添加规则和注解:
1 | <!--忽略建议 Set android:baselineAligned="false"--> |
18. Inefficient layout weight
在使用layout weight属性的时候,应保持相应属性为0dp;或者是在copy代码的时候忘记删除layout_weight代码导致lint检测报错
19. Nested layout weights
在布局进行嵌套使用时,父布局与子布局都使用了android:layout_weight,根据需求进行修改;
20. Useless parent layout
警告有未使用的父布局,或者是无用的父布局。
根据实际需求进行忽略或者是删除相应布局
21. Unused namespace
命名空间重复添加,或者是删除对应属性后,命名空间未删除,删除.
22. Hyphen can be replaced with dash
Replace “-“ with an “en dash” character (–, –)
为了符合人性化的开发,建议直接添加规则忽略
23. H Ellipsis string can be replaced with ellipsis character
处理同上
24. Duplicated icons under different names
存在不同命名的同文件的icons
目前的处理是添加规则忽略
25. Missing accessibility label
对EditTextView的使用,建议添加一个它的标签View
根据需要进行忽略 或者添加android:labelfor
26. Keyboard inaccessible widget
一个控件(比如图片),如果没有定义focusable(可聚焦的),却定义了是clickable(可点击的),那么是不能通过键盘访问的。所以,需要添加一个focusable=“true”;相当于指定可获取焦点.
27. Usage of showAsAction=always
建议使用”ifRoom”替换”always”
根据需求进行修改或者忽略
28. Missing inputType
This text field does not specify an inputType
建议为EditText指定inputType属性
29. Overdraw: Painting regions more than once
Possible overdraw: Root element paints background @color/actionbar_color with a theme that also paints a background (inferred theme is @style/ActionTheme_NoTitle)
存在过度绘制的可能性
但是这个报警有点牵强,所以还是先添加规则给过滤吧
30. Hardware Id Usage
获取设备相关信息,可以查看官方API,使用其替换方法
31. Incompatible Gradle Versions
不兼容依赖版本库,可通过打依赖树,进行查找
贴出常见的lint issueid和秒速,以供对照
1 | "ContentDescription": Image without contentDescription |
总结
还有遇到一些简单代码规范的问题,平时注意,就能规避,比如常见的宽高,写成了sp、xp;总之就是sp、xp、dp使用混乱等一些规范问题,或者是内存泄漏风险.