Was bedeutet @hide im Android-Quellcode?

120

Für den ActivityQuellcode Zeile 3898 (ganz unten):

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

Was heißt @hidedas

Ich habe festgestellt, dass ich public class ChildActivity extends Activity { ... }nicht verwenden / sehen kann Activity.isResumed(). Ist das normal? Wie kann ich darauf zugreifen?

Midnite
quelle

Antworten:

182

Android verfügt über zwei Arten von APIs, auf die über das SDK nicht zugegriffen werden kann.

Der erste befindet sich im Paket com.android.internal. Der zweite API-Typ ist eine Sammlung von Klassen und Methoden, die mit dem Attribut @hide Javadoc gekennzeichnet sind .

Ab Android 9 (API-Level 28) führt Google neue Einschränkungen für die Verwendung von Nicht-SDK-Schnittstellen ein , sei es direkt, über Reflection oder über JNI. Diese Einschränkungen werden immer dann angewendet, wenn eine App auf eine Nicht-SDK-Schnittstelle verweist oder versucht, deren Handle mithilfe von Reflection oder JNI abzurufen.

Vor API-Level 28 konnte jedoch weiterhin über Java Reflection auf die verborgenen Methoden zugegriffen werden. Das @hideAttribut ist nur ein Teil von Javadoc (auch Droiddoc), @hidewas einfach bedeutet, dass die Methode / Klasse / das Feld aus den API-Dokumenten ausgeschlossen ist.

Zum Beispiel kann das checkUidPermission()Verfahren in ActivityManager.javaGebrauch @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;
}

Wir können es jedoch durch Reflexion nennen:

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});
StarPinkER
quelle
1
Hallo @StarPinkER, kann ich die Erlaubnis "android.permission.CHANGE_COMPONENT_ENABLED_STATE" mit versteckter oder interner API oder durch Reflaktion erteilen?
Hardik
1
Überprüfen Sie diese Antwort zuerst. Diese Berechtigung ist eine Signatur- / Systemberechtigung. In den meisten Fällen können Sie diese Berechtigung nur erhalten, wenn es sich um Systemanwendungen handelt. Das bedeutet, dass Sie Android Source ändern müssen, um Ihre App zu akzeptieren, oder Ihre App zu einer System-App machen und signieren müssen. Sie können dies jedoch nur tun, wenn Sie Ihr eigenes Android-System erstellen. Reflexion kann mit "Verstecken" umgehen, aber die Logik des Android-Sicherheitssystems nicht ändern. Sie können sich vorstellen, wie wir ein Android-Gerät leicht angreifen können, wenn wir dazu in der Lage sind. @ Hardik
StarPinkER
2
Vielen Dank für die Antwort, aber ich denke, die Antwort enthält zwei Probleme. Korrigieren Sie mich, wenn ich falsch liege. Ich erhalte den Fehler classnotfound, wenn ich versuche, ihn mit "ActivityManager" anstelle von "android.app.ActivityManager" und "m.invoke (c" zu finden, sollte "m.invoke (null" für statische Methoden und "m" sein). Rufen Sie (o, ", wobei o ein Objekt vom Typ c ist, für dynamische Methoden auf. Entschuldigen Sie meine polnische Grammatik :)
lindenrovio
3
Nur ein Hinweis zur Reflexion: Da diese Methoden / Felder nicht Teil des offiziellen SDK sind, gibt es keine Garantie dafür, dass sie in zukünftigen Android-Versionen vorhanden sein werden.
sstn
2
Wenn die Anmerkung nur die Methode aus der Dokumentation entfernt, warum kann ich sie dann nicht trotzdem im Code verwenden?
Javier Delgado
25
  1. @hidewird für Dinge verwendet, die aus verschiedenen Gründen sichtbar sein müssen, aber nicht Teil der veröffentlichten API sind. Sie werden nicht in die Dokumentation aufgenommen, wenn die API automatisch aus der Quelle extrahiert wird.

  2. Du hast recht, du kannst es nicht überschreiben. Dies ist normal, das ist beabsichtigt, da es als markiert ist final. Sie sollten in der Lage sein, es zu verwenden , obwohl ein Editor es Ihnen möglicherweise nicht als eine der Optionen in der von ihm verwendeten Intelligenz anzeigt, da es mit markiert ist @hide, und Sie sollten Punkt 3 unten beachten.

  3. Sie sollten es überhaupt nicht verwenden, da es nicht Teil der API ist und die Entwickler es jederzeit entfernen können. Sie wären sogar in ihrem Recht, wenn sie sadistisch geneigt wären, es durch eine Funktion zu ersetzen, die das Gerät, auf dem es lief, zugemauert hat (wenn auch möglicherweise nicht im engeren rechtlichen Sinne).

paxdiablo
quelle
Oh ja ... es ist finalnatürlich, dass ich es nicht überschreiben kann. Entschuldigung, das ist mein Fehler: x
Midnite
Meinen Sie, es ist publicüber alle Klassen während der Entwicklungsphase. Aber es verhält sich wie privateoder /*package*/für Benutzer wie uns?
Mitternacht
Hmm ... Das ist nur ein Kommentar. Ich verstehe seine Bedeutung. Aber was und wo kann dieses Verhalten auf Codeebene durchgesetzt werden?
Mitternacht
1
Warum es öffentlich ist, kann ich nicht wirklich kommentieren. Möglicherweise ist die Code-Implementierung Activityauf viele Klassen verteilt, und alle müssen auf dieses Mitglied zugreifen. Unterm Strich ist, es ist öffentlich , aber nicht Teil der API bedeutet , dass Sie es auf eigene Gefahr.
Paxdiablo
1
@midnite, Eclipse hat einen eigenen Java-Compiler, der zweifellos in das Intellisense-Zeug integriert ist. Ich würde vorschlagen, wenn Sie dies mit dem Java SDK kompilieren, würde es gut kompilieren. Nicht, dass ich das natürlich
vorschlage
4

Die @hideAnmerkung bedeutet, dass diese Schnittstelle nicht Teil der öffentlichen API ist und nicht in Ihrem Code verwendet werden sollte. Die Methoden sind nur für den internen Gebrauch des AOSP bestimmt.

Google hat tatsächlich damit begonnen, die Verwendung von Nicht-SDK-Schnittstellen einzuschränken . Dies schließt mit gekennzeichnete Schnittstellen ein@hide

Die Methoden sind in vier Listen unterteilt:

  • Whitelist: das SDK
  • Light-Greylist: Nicht-SDK-Methoden / Felder, auf die noch zugegriffen werden kann.
  • Dunkelgrauliste:
    • Für Apps, deren Ziel-SDK unter API-Ebene 28 liegt: Jede Verwendung einer Dark Greylist-Oberfläche ist zulässig.
    • Für Apps, deren Ziel-SDK API-Level 28 oder höher ist: Gleiches Verhalten wie bei der Blacklist
  • Blacklist: Unabhängig vom Ziel-SDK eingeschränkt. Die Plattform verhält sich so, als ob die Schnittstelle nicht vorhanden wäre. Beispielsweise wird NoSuchMethodError / NoSuchFieldException ausgelöst, wenn die App versucht, es zu verwenden, und es wird nicht eingeschlossen, wenn die App die Liste der Felder / Methoden einer bestimmten Klasse kennen möchte.

Die Listen finden Sie hier: https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat

leonardkraemer
quelle