Что означает @hide в исходном коде Android?

Для Activity Исходный код, строка 3898 (близко к низу):

/**
 * @hide
 */
public final boolean isResumed() {
    return mResumed;
}

Что значит @hide имею в виду?

Я нашел свой public class ChildActivity extends Activity { ... } не может использовать / видеть Activity.isResumed(), Это нормально? Как я могу получить к нему доступ?

3 ответа

Решение

У Android есть два типа API, которые не доступны через SDK.

Первый находится в пакете com.android.internal. Второй тип API - это набор классов и методов, помеченных атрибутом @hide javadoc.

Начиная с Android 9 (уровень API 28), Google вводит новые ограничения на использование не SDK-интерфейсов, будь то напрямую, через отражение или через JNI. Эти ограничения применяются всякий раз, когда приложение ссылается на интерфейс не SDK или пытается получить его дескриптор, используя отражение или JNI.

Но до уровня API 28 к скрытым методам все еще можно получить доступ с помощью Java-отражения. Атрибут @hide является лишь частью javadoc(также droiddoc), поэтому @hide просто означает, что метод / класс / поле исключен из документации API.

Например, метод checkUidPermission в ActivityManager.java - это @hide.

/** @hide */
public static int checkUidPermission(String permission, int uid) {
    try {
        return AppGlobals.getPackageManager()
                .checkUidPermission(permission, uid);
    } catch (RemoteException e) {
        // Should never happen, but if it does... deny!
        Slog.e(TAG, "PackageManager is dead?!?", e);
    }
    return PackageManager.PERMISSION_DENIED;
}

Однако мы можем назвать это отражением.

Class c;
c = Class.forName("android.app.ActivityManager");
Method m = c.getMethod("checkUidPermission", new Class[] {String.class, int.class});
Object o = m.invoke(null, new Object[]{"android.permission.READ_CONTACTS", 10010});
  1. @hide используется для вещей, которые должны быть видны по разным причинам, но не являются частью опубликованного API. Они не будут включены в документацию, когда он автоматически извлекает API из источника.

  2. Вы правы, вы не можете переопределить это. Это нормально, так задумано, так как помечено как final, Вы должны быть в состоянии использовать его, хотя редактор может не показывать его вам как один из вариантов в любом интеллектуальном значении, которое он использует, потому что он отмечен @hide, и вы должны принять к сведению пункт 3 ниже.

  3. Вы не должны использовать его вообще, поскольку он не является частью API, и разработчики могут удалить его, когда захотят. Они даже были бы в пределах своих прав, если бы они были склонны к садистскому подходу, заменить его функцией, которая заложила бы устройство, на котором он работал (хотя, возможно, не в строгом юридическом смысле).

@hide аннотация означает, что этот интерфейс не является частью общедоступного API и не должен использоваться в вашем коде. Методы предназначены только для внутреннего использования AOSP.

Google фактически начал ограничивать использование не-SDK интерфейсов. Это включает интерфейсы, отмеченные @hide

Методы разделены на четыре списка:

  • белый список: SDK
  • light-greylist: не SDK методы / поля, которые все еще доступны.
  • темно-серый список:
    • Для приложений, чей целевой SDK ниже уровня API 28: разрешено каждое использование интерфейса "темного серого".
    • Для приложений с целевым SDK уровня API 28 или выше: такое же поведение, как и в черном списке
  • черный список: ограничен независимо от целевого SDK. Платформа будет вести себя так, как будто интерфейс отсутствует. Например, он будет генерировать исключение NoSuchMethodError/NoSuchFieldException всякий раз, когда приложение пытается его использовать, и не будет включать его, когда приложение хочет знать список полей / методов определенного класса.

Списки можно найти здесь: https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat

Другие вопросы по тегам