@UnsupportedAppUsage注解

在Android-R版本中,Google引入UnsupportedAppUsage注解以限制非SDK接口的外部访问,加强框架的安全性。此注解用于标记不支持外部应用使用的类成员,编译器会在编译时进行处理,生成CSV文件记录受保护的接口。如果应用尝试访问这些接口,编译将失败。这一措施旨在保护系统API,避免应用依赖非官方接口,同时警告开发者可能存在的风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在android-R中,google拓展了原本的UnsupportedAppUsage来限制framework中的某些定义无法被外部应用访问。采用这中方案来强化mainlane模式,强制厂商mainlane自身feature。google也拓展了systemApi注释来保护某些属性无法被sdk外部访问。

@UnsupportedAppUsage

这个注释简单来说就是不支持外部应用使用被此注释声明的变量或方法等

tools\platform-compat\java\android\compat\annotation\UnsupportedAppUsage.java

/**
 * Indicates that this non-SDK interface is used by apps. A non-SDK interface is a
 * class member (field or method) that is not part of the public SDK. Since the
 * member is not part of the SDK, usage by apps is not supported.
 *
 * <h2>If you are an Android App developer</h2>
 *
 * This annotation indicates that you may be able to access the member at runtime, but that
 * this access is discouraged and not supported by Android. If there is a value
 * for {@link #maxTargetSdk()} on the annotation, access will be restricted based
 * on the {@code targetSdkVersion} value set in your manifest.
 *
 * <p>Fields and methods annotated with this are likely to be restricted, changed
 * or removed in future Android releases. If you rely on these members for
 * functionality that is not otherwise supported by Android, consider filing a
 * <a href="http://g.co/dev/appcompat">feature request</a>.
 *
 * <h2>If you are an Android OS developer</h2>
 *
 * This annotation acts as a heads up that changing a given method or field
 * may affect apps, potentially breaking them when the next Android version is
 * released. In some cases, for members that are heavily used, this annotation
 * may imply restrictions on changes to the member.
 *
 * <p>This annotation also results in access to the member being permitted by the
 * runtime, with a warning being generated in debug builds. Which apps can access
 * the member is determined by the value of {@link #maxTargetSdk()}.
 *
 * <p>For more details, see go/UnsupportedAppUsage.
 *
 * {@hide}
 */
@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<PackageElement, String, List<Element>> annotatedElements) {
        SignatureConverter signatureConverter = new SignatureConverter(messager);

        for (PackageElement packageElement : annotatedElements.rowKeySet()) {
            Map<String, List<Element>> row = annotatedElements.row(packageElement);
            for (String enclosingElementName : row.keySet()) {
                List<String> 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);
                }
            }
        }
    }

1.在保存csv后,编译器就知道了当前类中那些属性被UnsupportedAppUsage保护了。

2.在编译其他模块时,在检查当前模块使用的内容时,会检查app是否引用了被注释保护的属性。

3.一旦检查没有通过,就会报编译错误,导致编译失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaowang_lj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值