在android-R中,google拓展了原本的UnsupportedAppUsage来限制framework中的某些定义无法被外部应用访问。采用这中方案来强化mainlane模式,强制厂商mainlane自身feature。google也拓展了systemApi注释来保护某些属性无法被sdk外部访问。
@UnsupportedAppUsage
这个注释简单来说就是不支持外部应用使用被此注释声明的变量或方法等
tools\platform-compat\java\android\compat\annotation\UnsupportedAppUsage.java
@Retention(CLASS)@Target({CONSTRUCTOR, METHOD, FIELD, TYPE})@Repeatable(UnsupportedAppUsage.Container.class)public @interface UnsupportedAppUsage {
@Retention(CLASS)可以看到这个注释是存在于class文件中,也就是说编译器会在编译当前java文件为class文件时保留此注释。
tools/platform-compat/java/android/processor/compat/unsupportedappusage/UnsupportedAppUsageProcessor.java
在UnsupportedAppUsageProcessor.java类中,编译器会在class文件处理阶段对UnsupportedAppUsage注释进行分析处理
@Override protected void process(TypeElement annotation, Table> annotatedElements) { SignatureConverter signatureConverter = new SignatureConverter(messager); for (PackageElement packageElement : annotatedElements.rowKeySet()) { Map> row = annotatedElements.row(packageElement); for (String enclosingElementName : row.keySet()) { List content = new ArrayList<>(); for (Element annotatedElement : row.get(enclosingElementName)) { String signature = signatureConverter.getSignature(types, annotation, annotatedElement); if (signature != null) { String annotationIndex = getAnnotationIndex(signature, annotation, annotatedElement); if (annotationIndex != null) {content.add(annotationIndex); } } } if (content.isEmpty()) { continue; } try { FileObject resource = processingEnv.getFiler().createResource(CLASS_OUTPUT,packageElement.toString(),enclosingElementName + GENERATED_INDEX_FILE_EXTENSION); try (PrintStream outputStream = new PrintStream(resource.openOutputStream())) { outputStream.println(CSV_HEADER); content.forEach(outputStream::println); } } catch (IOException exception) { messager.printMessage(ERROR, "Could not write CSV file: " + exception); } } } }
在保存csv后,编译器就知道了当前类中那些属性被UnsupportedAppUsage保护了。
在编译其他模块时,在检查当前模块使用的内容时,会检查app是否引用了被注释保护的属性。
一旦检查没有通过,就会报编译错误,导致编译失败。
来源地址:https://blog.csdn.net/xiaowang_lj/article/details/128368937