Apa arti @hide dalam kode sumber Android?


120

Untuk Activitykode sumber , baris 3898 (dekat paling bawah):

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

Apa @hidemaksudnya

Saya menemukan saya public class ChildActivity extends Activity { ... }tidak dapat menggunakan / melihat Activity.isResumed(). Apakah ini normal? Bagaimana cara mengaksesnya?

Jawaban:


182

Android memiliki dua jenis API yang tidak dapat diakses melalui SDK.

Yang pertama ada di dalam paket com.android.internal. Jenis API kedua adalah kumpulan kelas dan metode yang ditandai dengan atribut @hide Javadoc .

Mulai dari Android 9 (API level 28), Google memperkenalkan batasan baru pada penggunaan antarmuka non-SDK , baik secara langsung, melalui refleksi, atau melalui JNI. Pembatasan ini diterapkan setiap kali aplikasi mereferensikan antarmuka non-SDK atau mencoba untuk mendapatkan pegangannya menggunakan refleksi atau JNI.

Tetapi sebelum API level 28, metode tersembunyi masih bisa diakses melalui refleksi Java. The @hideatribut hanya bagian dari Javadoc (droiddoc juga), sehingga @hidehanya cukup berarti metode / kelas / lapangan dikeluarkan dari dokumentasi API.

Misalnya, checkUidPermission()metode yang ActivityManager.javadigunakan @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;
}

Namun, kita dapat menyebutnya dengan refleksi:

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
halo @StarPinkER dapatkah saya memberikan izin "android.permission.CHANGE_COMPONENT_ENABLED_STATE" menggunakan api tersembunyi atau internal atau dengan reflaksi?
Hardik

1
Cek jawaban ini dulu. Izin ini adalah izin tanda tangan / sistem. Dalam kebanyakan kasus, Anda tidak bisa mendapatkan izin ini kecuali itu adalah aplikasi sistem. Itu berarti Anda perlu memodifikasi Sumber Android untuk menerima aplikasi Anda atau menjadikan aplikasi Anda sebagai aplikasi sistem dan menandatanganinya. Namun, Anda tidak akan dapat melakukan ini kecuali Anda membuat Sistem Android Anda sendiri. Refleksi dapat menangani "persembunyian" tetapi tidak dapat mengubah logika Sistem Keamanan Android. Anda dapat membayangkan bagaimana kita dapat dengan mudah menyerang Perangkat Android jika kita mampu melakukan ini. @Hik
StarNews

2
Terima kasih atas jawabannya, tetapi saya pikir ada dua masalah dalam jawabannya, perbaiki saya jika saya salah. Saya mendapatkan error classnotfound jika mencoba menemukannya dengan "ActivityManager" bukan "android.app.ActivityManager" dan "m.invoke (c," tampaknya harus "m.invoke (null," untuk metode statis dan "m. invoke (o, ", di mana o adalah objek tipe c, untuk metode dinamis. Maaf untuk tata bahasa Polandia saya :)
lindenrovio

3
Hanya catatan tentang refleksi: Karena metode / kolom tersebut bukan bagian dari SDK resmi, tidak ada jaminan bahwa metode / kolom tersebut akan hadir dalam revisi Android mendatang.
sstn

2
Jika anotasi hanya menghapus metode dari dokumentasi, mengapa saya masih tidak dapat menggunakannya dalam kode?
Javier Delgado

25
  1. @hidedigunakan untuk hal-hal yang perlu terlihat karena berbagai alasan tetapi bukan bagian dari API yang diterbitkan. Mereka tidak akan disertakan dalam dokumentasi ketika secara otomatis mengekstrak API dari sumbernya.

  2. Anda benar, Anda tidak bisa menggantinya. Ini normal, itu memang disengaja, karena ditandai sebagai final. Anda harus dapat menggunakannya , meskipun editor mungkin tidak menunjukkannya kepada Anda sebagai salah satu pilihan dalam kecerdasan apa pun yang digunakannya karena ditandai dengan @hide, dan Anda harus memperhatikan poin 3 di bawah ini.

  3. Anda tidak boleh menggunakannya sama sekali karena ini bukan bagian dari API dan pengembang dapat menghapusnya kapan pun mereka mau. Mereka bahkan akan berada dalam hak mereka, jika mereka cenderung secara sadis, untuk menggantinya dengan fungsi yang memblokir perangkat yang dijalankannya (meskipun mungkin tidak dalam arti hukum yang ketat).


Oh ya ... finaltentu saja saya tidak bisa menggantinya. Maaf itu kesalahan saya: x
midnite

Maksud Anda, ini terjadi publicdi semua kelas selama tahap pengembangan. Tapi bertindak seperti privateatau /*package*/untuk pengguna seperti kami?
midnite

Hmm… Itu hanya sebuah komentar. saya mengerti artinya. Tapi apa dan di mana menegakkan perilaku ini di tingkat kode?
midnite

1
Mengapa ini publik, saya tidak bisa berkomentar. Mungkin penerapan kode Activitytersebar di banyak kelas dan mereka semua perlu mengakses anggota ini. Intinya adalah, ini publik tetapi bukan bagian dari API yang berarti Anda menggunakannya dengan risiko Anda sendiri.
paxdiablo

1
@midnite, Eclipse memiliki kompiler Java sendiri yang tidak diragukan lagi terintegrasi dengan hal-hal Intellisense. Saya akan menyarankan jika Anda mengkompilasi ini dengan Java SDK, itu akan dikompilasi dengan baik. Bukan berarti saya menyarankan hal ini, lihat poin 3.
paxdiablo

4

The @hidepenjelasan berarti bahwa antarmuka ini bukan bagian dari API publik dan tidak boleh digunakan dalam kode Anda. Metode ini hanya untuk penggunaan internal AOSP.

Google sebenarnya telah mulai membatasi penggunaan antarmuka non-sdk . Ini termasuk antarmuka yang ditandai dengan@hide

Metode tersebut diklasifikasikan menjadi empat daftar:

  • daftar putih: SDK
  • light-greylist: metode / kolom non SDK yang masih dapat diakses.
  • dark-greylist:
    • Untuk aplikasi yang SDK targetnya di bawah API level 28: setiap penggunaan antarmuka greylist gelap diizinkan.
    • Untuk aplikasi yang SDK targetnya adalah API level 28 atau lebih tinggi: perilaku yang sama seperti daftar hitam
  • daftar hitam: dibatasi apa pun SDK targetnya. Platform akan berperilaku seolah-olah antarmuka tidak ada. Misalnya, ini akan memunculkan NoSuchMethodError / NoSuchFieldException setiap kali aplikasi mencoba menggunakannya, dan tidak akan menyertakannya saat aplikasi ingin mengetahui daftar kolom / metode dari kelas tertentu.

Daftar tersebut dapat ditemukan di sini: https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.