问题
error: Bare field miSyncResult must be marked final, or moved behind accessors if mutable [MutableBareField]
解决方法
1.分析
Android中由于编译检查, 会将如下
public MiSyncResult miSyncResult;
这样的代码报该问题
让1.若是不可变的变量,则用final关键字修饰
2.若是可变的变量,则要改成用get;set;方法的accessors去进行取值和赋值,并降低属性的可见性为private等.
2. 修复示例
(1)不可变的变量,则用final关键字修饰
public final MiSyncResult miSyncResult;
(2)可变的变量,则要改成用get;set;方法的accessors去进行取值和赋值,并降低属性的可见性为private等
private String resultMessage;
@Nullable
public String getResultMessage() {
return resultMessage;
}
public void setResultMessage(@Nullable String resultMessage) {
this.resultMessage = resultMessage;
}
更多问题
1.同样的代码在r之前的Android源码编译中,并没有报这个错误;为何在r的编译中报了这个问题?
(1) 调研排查
(a) Google搜索相关字段和问题
发现有:
https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/percentlayout/percentlayout/api/api_lint.ignore?source=post_page---------------------------%2F&autodive=0%2F%2F%2F%2F%2F
设置了api_lint.ignore;
让部分源代码ignore, lint该检查
MutableBareField: androidx.percentlayout.widget.PercentLayoutHelper.PercentLayoutInfo#rightMarginPercent:
Bare field rightMarginPercent must be marked final, or moved behind accessors if mutable
(b) 在Android Code Search网址中https://cs.android.com/中搜索相关错误log所在的源码
发现有:
https://cs.android.com/android/platform/superproject/+/master:tools/metalava/src/main/java/com/android/tools/metalava/ApiLint.kt;l=962?q=moved%20behind%20accessors%20if%20mutable%20&start=1
在ApiLint.kt的962行有检查并报告该错误.
( c ) 从上述源码中发现该代码在metalava工具中
metalava
(Also know as " doclava2", but deliberately not named doclava2 since crucially it does not generate docs; it’s intended only for metadata extraction and generation.)
metalava is a metadata generator intended for the Android source tree, use for a number of purposes:
- Allow extracting the API(into signature text files, into stub API files(which in turn get compiled into android.jar, the Android SDK library) and more importantly to hide code intended to be implementation only, driven by javadoc comments like @hide, @$doconly, @removed, etc, as well as various annotations.
- Extracting source level annotations into external annotations file (such as the typedef annotations, whick cannot be stored in the SDK as .class level annotaions).
- Diffing versions of the API and determining whether a newer version is compatible with the old version.
参考:https://cs.android.com/android/platform/superproject/+/master:tools/metalava/
(d)从上述metalava知识中得出
(d-1)android.jar用于相应app的代码编译却不会打包进入apk; 实际apk会调用具体device中的framework.jar
(d-2) android.jar作为公共提供的API需要保证接口的稳定并需要维护.因此才会有最开始所述的严格检查的报错log(Android R版本加强了这样的报错级别到Error).
(d-3) 所以解决该问题还可以执行的方法就是,将报错的所有代码都标记为"@hide"; 不参与到metalava的API抽取中,这样就不会报错了.
另外可参考:
(1)What is android.jar ? What does it include?
https://stackoverflow.com/questions/50283073/what-is-android-jar-what-does-it-include
(2)[Android][Framework]系统jar包,sdk的制作及引用
http://wossoneri.github.io/2018/12/09/[Android][Framework]mastering-system-jar-and-sdk/
(3)一张图看懂Android编译流程
https://www.jianshu.com/p/04eabba51db0
[补充知识 ] lint原理与知识
lint 一个代码扫描工具,可帮助发现并更正代码结构质量的问题.
参考:https://developer.android.com/studio/write/lint?hl=zh-cn