背景
在android-R中,google拓展了原本的UnsupportedAppUsage来限制framework中的某些定义无法被外部应用访问。采用这中方案来强化mainlane模式,强制厂商mainlane自身feature。google也拓展了systemApi注释来保护某些属性无法被sdk外部访问。
以WifiConfiguration为例,apChannel和apBand无法被外部程序访问。
UnsupportedAppUsage
这个注释简单来说就是不支持外部应用使用被此注释声明的变量或方法等。
我们可以简单的记住这个注释的特性,但是本人在学习java过程中唯独对注释这部分跳过了。所以迷惑了好久,这里简单的分享一下google是如何做到的。
首先,@Retention(CLASS)可以看到这个注释是存在于class文件中,也就是说编译器会在编译当前java文件为class文件时保留此注释。
其次,我们来看下处理函数。每个注释都会在处理函数中进行对此注释的独特解释。一些为aapt2提供的,一些事自定义的。在UnsupportedAppUsageProcessor.java类中,编译器会在class文件处理阶段对UnsupportedAppUsage注释进行分析处理。如下:
这里着重是获取了当前编译环境下,使用此注释的module的signature,也就是使用此注释的方法,变量或构造函数。并通过IO输出到类的通用目录下以csv格式保存。
这里仍然没有看到编译器是怎么判断一个外部应用是否访问被注释的内容的,所以一下皆为猜测。
1.在保存csv后,编译器就知道了当前类中那些属性被UnsupportedAppUsage保护了。
2.在编译其他模块时,在检查当前模块使用的内容时,会检查app是否引用了被注释保护的属性。
3.一旦检查没有通过,就会报编译错误,导致编译失败。
SystemApi
对比Q的不同,R明确了此注释保护属性的使用范围。
对于以上枚举的表述,基本认定为只有系统开发者可以访问被systemApi控制的属性。
1.私有应用 - 基本为内置应用,系统应用,settings,systemUI等
2.模块库 - wifi-service.jar services.jar等
3.systemserver - 这个没啥可以说的,必须给权限
此外,系统开发者可以限制自身的接口仅能被哪些属性的模块访问。类似下方的声明:
总结
对于google来讲,想要推行mainlane计划仅仅靠要求是不行的。也要通过CTS GTS以及注释控制,架构变化等多方面措施逼迫厂商不得不mainlane。这也是对厂商实力的一种考验。并且个人认为,mainlane带来的好处对用来讲是非常明显的。可以促使google安全补丁更快速的释放到用户设备中。厂商可以将自身的克制化做的更加独立,有助于提升整个系统的体验。
借助这次google的独特变化,个人也对java语言的认识有了更加明显的提升。