Що означає @hide у вихідному коді Android?


120

Для Activityвихідного коду , рядок 3898 (внизу):

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

Що @hideозначає?

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

Відповіді:


182

Android має два типи API, які недоступні через SDK.

Перший знаходиться в упаковці com.android.internal. Другий тип API - це набір класів і методів, які позначені атрибутом @hide Javadoc .

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

Але перед рівнем API 28, до прихованих методів все-таки можна отримати доступ через відображення Java. @hideАтрибут є лише частиною Javadoc (droiddoc також), так що @hideпросто означає , що метод / клас / поле виключений з API Docs.

Наприклад, 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
Привіт @StarPinkER чи можу я надати "android.permission.CHANGE_COMPONENT_ENABLED_STATE" дозволу, використовуючи приховані або внутрішні api або шляхом відбиття?
Хардік

1
Спершу перевірте цю відповідь . Цей дозвіл є дозволом на підпис / систему. У більшості випадків ви не можете отримати цей дозвіл, якщо це не системні програми. Це означає, що вам потрібно змінити джерело Android, щоб прийняти додаток або зробити його додатком системним і підписати його. Однак ви не зможете цього зробити, якщо не зробите власну систему Android. Відображення може впоратися зі «приховуванням», але воно не може змінити логіку системи безпеки Android. Ви можете собі уявити, як ми можемо легко атакувати пристрій Android, якщо нам це вдається. @Hardik
StarPinkER

2
Дякую за відповідь, але я думаю, що у відповіді є дві проблеми, виправте мене, якщо я помиляюся. Я отримую classnotfound помилку, якщо намагаюся знайти її за допомогою "ActivityManager" замість "android.app.ActivityManager" та "m.invoke (c", здається, має бути "m.invoke (null") для статичних методів та "m. виклик (o, ", де o - об'єкт типу c, для динамічних методів. Вибачте за мою польську граматику :)
lindenrovio

3
Лише зауваження щодо роздумів: Оскільки ці методи / поля не є частиною офіційного пакета SDK, немає гарантії, що вони будуть присутні в будь-якій майбутній версії Android.
sstn

2
Якщо анотація видаляє метод лише з документації, чому я не можу все-таки використовувати його в коді?
Хав'єр Дельгадо

25
  1. @hideвикористовується для речей, які повинні бути видимими з різних причин, але не є частиною опублікованого API. Вони не будуть включені в документацію, коли вона автоматично вилучає API з джерела.

  2. Ти маєш рацію, не можеш це перемогти. Це нормально, це за дизайном, оскільки він позначений як final. Ви повинні мати можливість використовувати його, хоча редактор може не показувати вам його як один із варіантів у будь-якому інтелісценсі, який він використовує, оскільки він позначений @hide, і вам слід взяти до уваги пункт 3 нижче.

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


О так ... це, finalзвичайно, я не можу це перекрити. Вибачте, це моя помилка: x
midnite

Ви маєте на увазі, що це є publicу всіх класах на етапі розвитку. Але це діє так, як privateабо /*package*/таким користувачам, як ми?
midnite

Хм ... Це просто коментар. я розумію його значення. Але що і де застосовувати таку поведінку на рівні коду?
midnite

1
Чому це публічно, я не можу реально коментувати. Можливо, впровадження коду Activityпоширюється в багатьох класах, і всі вони потребують доступу до цього учасника. Суть полягає в тому, що вона є загальнодоступною, але не є частиною API, тобто ви використовуєте її на свій страх і ризик.
paxdiablo

1
@midnite, Eclipse має власний компілятор Java, який, без сумніву, інтегрований з інтеліссенсом. Я б запропонував, якби ви компілювали це за допомогою Java SDK, він склав би чудово. Не те, що я пропоную це, звичайно, див. Пункт 3.
paxdiablo

4

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

Google фактично почав обмежувати використання не-sdk-інтерфейсів . Сюди входять інтерфейси, позначені символом@hide

Методи класифікуються на чотири списки:

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.