Pratinjau Developer Android 11 kedua kini tersedia, uji dan sampaikan masukan Anda.

Memperbaiki pemeriksaan kode dengan anotasi

Penggunaan alat pemeriksaan kode seperti Lint dapat membantu Anda menemukan masalah dan memperbaiki kode, tetapi alat pemeriksaan hanya bisa menyimpulkan sejauh itu. ID resource Android, misalnya, menggunakan int untuk mengidentifikasi string, grafis, warna, dan jenis resource lainnya, sehingga alat pemeriksaan tidak bisa membedakan kapan Anda menetapkan resource string saat Anda semestinya menetapkan resource warna. Situasi ini dapat mengakibatkan aplikasi Anda salah dirender atau gagal dijalankan sama sekali, sekalipun Anda menggunakan pemeriksaan kode.

Anotasi memungkinkan Anda menyediakan petunjuk bagi fitur pemeriksaan kode seperti Lint, untuk membantu mendeteksi masalah kode yang tidak begitu kentara. Anotasi ditambahkan sebagai tag metadata yang dilampirkan ke variabel, parameter, dan nilai kembalian untuk memeriksa nilai kembalian metode, parameter yang diteruskan, variabel lokal, dan kolom. Saat digunakan dengan alat pemeriksaan kode, anotasi dapat membantu Anda mendeteksi masalah, seperti pengecualian pointer null dan konflik jenis resource.

Android mendukung berbagai anotasi melalui Annotations Support Library. Anda dapat mengakses library ini melalui paket android.support.annotation.

Catatan: Jika ada modul yang memiliki dependensi pada pemroses anotasi, Anda harus menggunakan konfigurasi dependensi `annotationProcessor` untuk menambahkan dependensi tersebut. Untuk mempelajari lebih lanjut, baca Menggunakan konfigurasi dependensi pemroses anotasi.

Menambahkan anotasi ke project Anda

Untuk mengaktifkan anotasi dalam project Anda, tambahkan dependensi support-annotations ke library atau aplikasi Anda. Setiap anotasi yang ditambahkan selanjutnya diperiksa saat Anda menjalankan pemeriksaan kode atau tugas lint.

Menambahkan dependensi library support annotation

Library Support Annotation dipublikasikan di Repository Maven Google. Untuk menambahkan library Support Annotation ke project Anda, sertakan baris berikut dalam blok dependencies file build.gradle Anda:

    dependencies {
        implementation 'com.android.support:support-annotations:28.0.0'
    }
    
Selanjutnya, di toolbar atau notifikasi sinkronisasi yang muncul, klik Sync Now.

Jika Anda menggunakan anotasi dalam modul library Anda sendiri, anotasi tersebut akan disertakan sebagai bagian dari artefak Android Archive (AAR) dalam format XML di file annotations.zip. Menambahkan dependensi support-annotations tidak memperkenalkan dependensi untuk pengguna downstream mana pun dari library Anda.

Catatan: Jika menggunakan library appcompat, Anda tidak perlu menambahkan dependensi support-annotations. Karena library appcompat sudah bergantung pada library anotasi, Anda memiliki akses ke anotasi tersebut.

Untuk daftar lengkap anotasi yang disertakan dalam repositori dukungan, periksa referensi library Support Annotations atau gunakan fitur pelengkapan otomatis untuk menampilkan opsi yang tersedia untuk pernyataan import android.support.annotation..

Menjalankan pemeriksaan kode

Untuk memulai pemeriksaan kode dari Android Studio, yang menyertakan validasi anotasi dan pemeriksaan Lint otomatis, pilih Analyze > Inspect Code dari panel menu. Android Studio menampilkan pesan konflik untuk menandai potensi masalah apabila kode Anda bertentangan dengan anotasi dan menyarankan penyelesaian yang memungkinkan.

Anda juga dapat memaksakan anotasi dengan menjalankan tugas lint menggunakan command line. Meskipun cara ini mungkin berguna untuk menandai masalah server continuous integration, perhatikan bahwa tugas lint tidak memaksakan anotasi nullness (hanya Android Studio yang melakukannya). Untuk informasi selengkapnya mengenai mengaktifkan dan menjalankan pemeriksaan Lint, lihat Memperbaiki Kode dengan Lint.

Perhatikan, meskipun konflik anotasi menghasilkan peringatan, peringatan ini tidak mencegah aplikasi Anda melakukan kompilasi.

Anotasi nullness

Tambahkan anotasi @Nullable dan @NonNull untuk memeriksa nullness variabel, parameter, atau nilai kembalian tertentu. Anotasi @Nullable menunjukkan variabel, parameter, atau nilai kembalian yang boleh bernilai null, sedangkan @NonNull menunjukkan variabel, parameter, atau nilai kembalian yang tidak boleh bernilai null.

Misalnya, jika sebuah variabel lokal yang berisi nilai null diteruskan sebagai parameter ke metode dengan anotasi @NonNull yang terkait dengan parameter tersebut, pembuatan kode akan menghasilkan peringatan yang mengindikasikan konflik bukan-null. Di sisi lain, jika Anda mencoba mereferensikan hasil metode yang ditandai dengan @Nullable, tanpa terlebih dahulu memeriksa apakah hasilnya bernilai null, peringatan nullness akan dimunculkan. Sebaiknya Anda hanya menggunakan @Nullable dengan nilai kembalian metode jika setiap penggunaan metode ini perlu dipastikan secara eksplisit nilai null-nya.

Contoh berikut mengaitkan anotasi @NonNull ke parameter context dan attrs untuk memeriksa bahwa nilai parameter yang diteruskan bukanlah null. Contoh ini juga memeriksa bahwa metode onCreateView() itu sendiri tidak menampilkan null: Harap diperhatikan bahwa pada Kotlin, kita tidak perlu menggunakan anotasi @NonNull karena akan otomatis ditambahkan ke bytecode yang dihasilkan saat kita menentukan jenis yang non-nullable:

Kotlin

    import android.support.annotation.NonNull
    ...

        /** Add support for inflating the <fragment> tag. **/
        fun onCreateView(
                name: String?,
                context: Context,
                attrs: AttributeSet
        ): View? {
            ...
        }
    ...
    

Java

    import android.support.annotation.NonNull;
    ...

        /** Add support for inflating the <fragment> tag. **/
        @NonNull
        @Override
        public View onCreateView(String name, @NonNull Context context,
          @NonNull AttributeSet attrs) {
          ...
          }
    ...
    

Analisis nullability

Android Studio mendukung operasi analisis nullability untuk otomatis menyimpulkan dan memasukkan anotasi nullness di kode Anda. Analisis nullability akan memindai kontrak di seluruh hierarki metode dalam kode Anda untuk mendeteksi:

  • Metode panggilan yang dapat menghasilkan nilai null
  • Metode yang tidak boleh menghasilkan nilai null
  • Variabel, seperti kolom, variabel lokal, dan parameter, yang boleh bernilai null
  • Variabel, seperti kolom, variabel lokal, dan parameter, yang tidak boleh bernilai null

Selanjutnya, analisis akan otomatis menyisipkan anotasi null yang sesuai di lokasi yang dideteksi.

Untuk menjalankan analisis nullability di Android Studio, pilih Analyze > Infer Nullity. Android Studio akan menyisipkan anotasi @Nullable dan @NonNull Android di lokasi yang terdeteksi dalam kode Anda. Setelah menjalankan analisis null sebaiknya Anda memverifikasi anotasi yang dimasukkan itu.

Catatan: Saat menambahkan anotasi nullness, alat pelengkapan otomatis mungkin menyarankan anotasi @Nullable dan @NotNull IntelliJ, bukan anotasi null Android, dan dapat otomatis mengimpor library yang terkait. Namun, pemeriksa Lint Android Studio hanya mencari anotasi null Android. Saat memverifikasi anotasi, konfirmasikan bahwa project Anda menggunakan anotasi null Android agar pemeriksa Lint dapat memberi tahu Anda dengan tepat selama pemeriksaan kode.

Anotasi resource

Memvalidasi jenis resource dapat berguna karena referensi Android ke berbagai resource, misalnya resource drawable dan string, diteruskan sebagai integer. Kode yang mengharapkan parameter mereferensikan jenis resource tertentu, misalnya Drawable, dapat menerima jenis referensi int yang diharapkan, tetapi sebenarnya mereferensikan jenis resource berbeda, misalnya resource R.string.

Sebagai contoh, tambahkan anotasi @StringRes untuk memeriksa bahwa parameter resource berisi referensi R.string, seperti ditunjukkan di sini:

Kotlin

    abstract fun setTitle(@StringRes resId: Int)
    

Java

    public abstract void setTitle(@StringRes int resId)
    

Selama pemeriksaan kode, anotasi akan menghasilkan peringatan jika referensi R.string tidak diteruskan dalam parameter.

Anotasi untuk jenis resource lainnya, seperti @DrawableRes, @DimenRes, @ColorRes, dan @InterpolatorRes dapat ditambahkan menggunakan format anotasi yang sama dan dijalankan selama pemeriksaan kode. Jika parameter Anda mendukung banyak jenis resource, Anda dapat menempatkan lebih dari satu anotasi ini dalam parameter tertentu. Gunakan @AnyRes untuk menunjukkan bahwa parameter yang dianotasi dapat berupa resource R jenis apa pun.

Meskipun Anda dapat menggunakan @ColorRes untuk menentukan bahwa sebuah parameter harus berupa resource warna, integer warna (dalam format RRGGBB atau AARRGGBB) tidak dikenal sebagai resource warna. Sebagai gantinya, gunakan anotasi @ColorInt untuk menunjukkan bahwa suatu parameter harus berupa integer warna. Alat build akan menandai kode salah yang meneruskan ID resource warna seperti android.R.color.black, bukannya integer warna, ke metode yang dianotasi.

Anotasi thread

Anotasi thread memeriksa apakah sebuah metode dipanggil dari thread jenis tertentu. Berikut ini adalah anotasi thread yang didukung:

Catatan: Alat build memperlakukan anotasi @MainThread dan @UiThread sebagai dapat dipertukarkan, sehingga Anda dapat memanggil metode @UiThread dari metode @MainThread, dan sebaliknya. Akan tetapi, ada kemungkinan thread UI berbeda dengan thread utama pada aplikasi sistem yang memiliki beberapa tampilan dalam thead berbeda. Karena itu, sebaiknya Anda menganotasi metode yang terkait dengan hierarki tampilan aplikasi dengan @UiThread, dan hanya menganotasi metode yang terkait dengan siklus proses aplikasi dengan @MainThread.

Jika semua metode di sebuah class memiliki persyaratan threading yang sama, Anda dapat menambahkan anotasi thread tunggal ke class tersebut guna memverifikasi bahwa semua metode dalam kelas ini dipanggil dari jenis thread yang sama.

Penggunaan yang umum dari anotasi thread adalah untuk memvalidasi penggantian metode dalam class AsyncTask karena class ini menjalankan operasi latar belakang dan hanya memublikasikan hasil di thread UI.

Anotasi batasan nilai

Gunakan anotasi @IntRange, @FloatRange, dan @Size untuk memvalidasi nilai dari parameter yang diteruskan. Baik @IntRange maupun @FloatRange berguna terutama saat diterapkan pada parameter yang rentangnya sering salah didapatkan oleh pengguna.

Anotasi @IntRange memvalidasi bahwa nilai parameter integer atau long berada dalam rentang yang ditetapkan. Contoh berikut memastikan bahwa parameter alpha berisi nilai integer dari 0 sampai 255:

Kotlin

    fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }
    

Java

    public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }
    

Anotasi @FloatRange memeriksa bahwa nilai parameter float atau double berada dalam rentang nilai titik mengambang yang ditetapkan. Contoh berikut memastikan bahwa parameter alpha berisi nilai float dari 0,0 sampai 1,0:

Kotlin

    fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}
    

Java

    public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}
    

Anotasi @Size memeriksa ukuran kumpulan atau array, serta panjang string. Anotasi @Size dapat digunakan untuk memverifikasi properti berikut:

  • Ukuran minimum (misalnya @Size(min=2))
  • Ukuran maksimum (misalnya @Size(max=2))
  • Ukuran persis (misalnya @Size(2))
  • Angka jika ukuran harus berupa kelipatan (misalnya @Size(multiple=2))

Misalnya, @Size(min=1) memeriksa apakah sebuah koleksi tidak kosong, dan @Size(3) memvalidasi bahwa array mengandung persis tiga nilai. Contoh berikut memastikan bahwa array location berisi setidaknya satu elemen:

Kotlin

    fun getLocation(button: View, @Size(min=1) location: IntArray) {
        button.getLocationOnScreen(location)
    }
    

Java

    void getLocation(View button, @Size(min=1) int[] location) {
        button.getLocationOnScreen(location);
    }
    

Anotasi izin

Gunakan anotasi @RequiresPermission untuk memvalidasi izin pemanggil metode. Untuk memeriksa keberadaan izin tunggal dari daftar izin yang valid, gunakan atribut anyOf. Untuk memeriksa keberadaan sekumpulan izin, gunakan atribut allOf. Contoh berikut menganotasi metode setWallpaper() untuk memastikan bahwa pemanggil metode memiliki izin permission.SET_WALLPAPERS:

Kotlin

    @RequiresPermission(Manifest.permission.SET_WALLPAPER)
    @Throws(IOException::class)
    abstract fun setWallpaper(bitmap: Bitmap)
    

Java

    @RequiresPermission(Manifest.permission.SET_WALLPAPER)
    public abstract void setWallpaper(Bitmap bitmap) throws IOException;
    

Contoh ini mengharuskan pemanggil metode copyFile() memiliki izin baca dan tulis ke penyimpanan eksternal:

Kotlin

    @RequiresPermission(allOf = [
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    ])
    fun copyFile(dest: String, source: String) {
        ...
    }

Java

    @RequiresPermission(allOf = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE})
    public static final void copyFile(String dest, String source) {
        //...
    }
    

Untuk izin terkait intent, tempatkan persyaratan izin pada kolom string yang menentukan nama tindakan intent:

Kotlin

    @RequiresPermission(android.Manifest.permission.BLUETOOTH)
    const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"
    

Java

    @RequiresPermission(android.Manifest.permission.BLUETOOTH)
    public static final String ACTION_REQUEST_DISCOVERABLE =
                "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
    

Untuk izin terkait penyedia konten yang mengharuskan izin akses baca dan tulis terpisah, gabung setiap persyaratan izin dalam anotasi @RequiresPermission.Read atau @RequiresPermission.Write :

Kotlin

    @RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS))
    @RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS))
    val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")
    

Java

    @RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
    @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
    public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
    

Izin tidak langsung

Jika izin bergantung pada nilai spesifik yang dimasukkan ke parameter metode, gunakan @RequiresPermission pada parameter itu sendiri, tanpa mencantumkan izin spesifiknya. Misalnya, metode startActivity(Intent) menggunakan izin tidak langsung pada intent yang diteruskan ke metode:

Kotlin

    abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)
    

Java

    public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)
    

Saat Anda menggunakan izin tidak langsung, alat build akan menjalankan analisis alur data untuk memeriksa apakah argumen yang diteruskan ke dalam metode memiliki anotasi @RequiresPermission. Selanjutnya, alat build akan memberlakukan semua anotasi yang ada dari parameter pada metode itu sendiri. Dalam contoh startActivity(Intent), anotasi di class Intent menyebabkan munculnya peringatan tentang penggunaan startActivity(Intent) yang tidak valid saat intent tanpa izin yang sesuai diteruskan ke metode, seperti ditunjukkan pada gambar 1.

Gambar 1. Peringatan yang dihasilkan dari anotasi izin tidak langsung pada metode startActivity(Intent).

Alat build mengeluarkan peringatan tentang startActivity(Intent) dari anotasi pada nama tindakan intent yang terkait dalam class Intent:

Kotlin

    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    @RequiresPermission(Manifest.permission.CALL_PHONE)
    const val ACTION_CALL = "android.intent.action.CALL"
    

Java

    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    @RequiresPermission(Manifest.permission.CALL_PHONE)
    public static final String ACTION_CALL = "android.intent.action.CALL";
    

Jika perlu, Anda dapat mengganti @RequiresPermission dengan @RequiresPermission.Read dan/atau @RequiresPermission.Write saat menganotasikan parameter metode. Namun, untuk izin tidak langsung, @RequiresPermission tidak boleh digunakan bersama salah satu anotasi izin, baik baca maupun tulis.

Anotasi nilai kembalian

Gunakan anotasi @CheckResult untuk memvalidasi bahwa hasil atau nilai kembalian dari sebuah metode benar-benar digunakan. Daripada menganotasi setiap metode non-void dengan @CheckResult, tambahkan anotasi ini untuk memperjelas hasil metode yang berpotensi membingungkan. Misalnya, developer Java baru sering keliru menganggap bahwa <String>.trim() menghapus spasi putih dari string asli. Menganotasi metode dengan @CheckResult menandai penggunaan <String>.trim() di mana pemanggil tidak melakukan apa pun terhadap nilai kembalian metode.

Contoh berikut menganotasi metode checkPermissions() untuk memastikan nilai kembalian metode benar-benar direferensikan. Contoh ini juga menyebutkan enforcePermission() sebagai metode yang akan disarankan ke developer sebagai pengganti:

Kotlin

    @CheckResult(suggest = "#enforcePermission(String,int,int,String)")
    abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int
    

Java

    @CheckResult(suggest="#enforcePermission(String,int,int,String)")
    public abstract int checkPermission(@NonNull String permission, int pid, int uid);
    

Anotasi CallSuper

Gunakan anotasi @CallSuper untuk memvalidasi bahwa metode pengganti memanggil implementasi super untuk metode tersebut. Contoh berikut menganotasi metode onCreate() untuk memastikan bahwa implementasi metode pengganti memanggil super.onCreate():

Kotlin

    @CallSuper
    override fun onCreate(savedInstanceState: Bundle?) {
    }
    

Java

    @CallSuper
    protected void onCreate(Bundle savedInstanceState) {
    }
    

Anotasi Typedef

Gunakan anotasi @IntDef dan @StringDef agar Anda dapat membuat anotasi terenumerasi untuk kumpulan integer dan string untuk memvalidasi referensi kode jenis lainnya. Anotasi Typedef memastikan bahwa parameter, nilai kembalian, atau kolom tertentu mereferensikan set konstanta tertentu. Anotasi ini juga memungkinkan pelengkapan kode untuk otomatis menawarkan konstanta yang diizinkan.

Anotasi Typedef menggunakan @interface untuk mendeklarasikan jenis anotasi terenumerasi yang baru. Anotasi @IntDef dan @StringDef, serta @Retention, menganotasi anotasi baru ini dan diperlukan agar dapat menentukan jenis terenumerasi. Anotasi @Retention(RetentionPolicy.SOURCE) memberi tahu compiler untuk tidak menyimpan data anotasi terenumerasi dalam file .class.

Contoh berikut mengilustrasikan langkah-langkah untuk membuat anotasi yang memastikan bahwa nilai yang diteruskan sebagai parameter metode mereferensikan salah satu konstanta yang ditentukan:

Kotlin

    import android.support.annotation.IntDef
    //...
    // Define the list of accepted constants and declare the NavigationMode annotation
    @Retention(AnnotationRetention.SOURCE)
    @IntDef(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS)
    annotation class NavigationMode

    // Declare the constants
    const val NAVIGATION_MODE_STANDARD = 0
    const val NAVIGATION_MODE_LIST = 1
    const val NAVIGATION_MODE_TABS = 2

    abstract class ActionBar {

        // Decorate the target methods with the annotation
        // Attach the annotation
        @get:NavigationMode
        @setparam:NavigationMode
        abstract var navigationMode: Int

    }
    

Java

    import android.support.annotation.IntDef;
    //...
    public abstract class ActionBar {
        //...
        // Define the list of accepted constants and declare the NavigationMode annotation
        @Retention(RetentionPolicy.SOURCE)
        @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
        public @interface NavigationMode {}

        // Declare the constants
        public static final int NAVIGATION_MODE_STANDARD = 0;
        public static final int NAVIGATION_MODE_LIST = 1;
        public static final int NAVIGATION_MODE_TABS = 2;

        // Decorate the target methods with the annotation
        @NavigationMode
        public abstract int getNavigationMode();

        // Attach the annotation
        public abstract void setNavigationMode(@NavigationMode int mode);
    }
    

Saat Anda membuat kode ini, peringatan akan dimunculkan jika parameter mode tidak mereferensikan salah satu konstanta yang ditentukan (NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, atau NAVIGATION_MODE_TABS).

Anda juga dapat menggabungkan @IntDef dan @IntRange untuk menunjukkan bahwa integer dapat berupa sekumpulan konstanta tertentu atau nilai dalam suatu rentang.

Mengaktifkan penggabungan konstanta dengan flag

Jika pengguna dapat menggabungkan konstanta yang diizinkan dengan sebuah flag (misalnya |, &, ^, dan seterusnya), Anda dapat menetapkan anotasi dengan atribut flag untuk memeriksa apakah parameter atau nilai kembalian mereferensikan pola yang valid. Contoh berikut akan membuat anotasi DisplayOptions dengan daftar konstanta DISPLAY_ yang valid:

Kotlin

    import android.support.annotation.IntDef
    ...

    @IntDef(flag = true, value = [
        DISPLAY_USE_LOGO,
        DISPLAY_SHOW_HOME,
        DISPLAY_HOME_AS_UP,
        DISPLAY_SHOW_TITLE,
        DISPLAY_SHOW_CUSTOM
    ])
    @Retention(AnnotationRetention.SOURCE)
    annotation class DisplayOptions
    ...
    

Java

    import android.support.annotation.IntDef;
    ...

    @IntDef(flag=true, value={
            DISPLAY_USE_LOGO,
            DISPLAY_SHOW_HOME,
            DISPLAY_HOME_AS_UP,
            DISPLAY_SHOW_TITLE,
            DISPLAY_SHOW_CUSTOM
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface DisplayOptions {}

    ...
    

Saat Anda membuat kode dengan flag anotasi, peringatan akan dimunculkan jika parameter yang didekorasi atau nilai kembalian tidak mereferensikan pola yang valid.

Anotasi keep

Anotasi @Keep memastikan bahwa class atau metode yang dianotasi tidak dihapus saat kode diperkecil selama proses build. Anotasi ini biasanya ditambahkan ke metode dan class yang diakses melalui refleksi untuk mencegah compiler menganggap bahwa kode tidak digunakan.

Perhatian: Class dan metode yang dianotasi menggunakan @Keep akan selalu muncul di APK aplikasi, sekalipun Anda tidak pernah mereferensikan class dan metode tersebut dalam logika aplikasi Anda.

Agar ukuran aplikasi tetap kecil, pertimbangkan perlu tidaknya mempertahankan setiap anotasi @Keep dalam aplikasi Anda. Jika Anda menggunakan refleksi untuk mengakses class atau metode yang dianotasi, gunakan kondisional -if dalam aturan ProGuard, dengan menentukan class yang membuat panggilan refleksi tersebut.

Untuk informasi selengkapnya tentang cara memperkecil kode dan menentukan kode mana yang sebaiknya tidak dihapus, lihat Menyingkat Kode dan Resource.

Anotasi visibilitas kode

Gunakan anotasi berikut untuk menunjukkan visibilitas bagian kode tertentu, seperti metode, class, kolom, atau paket.

Memperlihatkan untuk pengujian

Anotasi @VisibleForTesting menunjukkan bahwa metode yang dianotasi terlihat lebih mencolok daripada biasanya agar metode tersebut lebih mudah diuji. Anotasi ini memiliki argumen otherwise opsional yang memungkinkan Anda menentukan visibilitas metode jika bukan untuk membuatnya terlihat saat pengujian. Lint menggunakan argumen otherwise untuk memberlakukan visibilitas yang diinginkan.

Dalam contoh berikut, myMethod() biasanya adalah private, tetapi metode ini merupakan paket-pribadi untuk pengujian. Dengan penetapan VisibleForTesting.PRIVATE di bawah, lint akan menampilkan pesan jika metode ini dipanggil dari luar konteks yang diizinkan oleh akses private, misalnya dari unit kompilasi yang berbeda.

Kotlin

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    fun myMethod() {
        ...
    }
    

Java

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    void myMethod() { ... }
    

Anda juga dapat menentukan @VisibleForTesting(otherwise = VisibleForTesting.NONE) untuk menunjukkan bahwa sebuah metode hanya ada untuk pengujian. Formatnya sama dengan penggunaan @RestrictTo(TESTS). Keduanya menjalankan pemeriksaan lint yang sama.

Membatasi API

Anotasi @RestrictTo menunjukkan bahwa akses ke API teranotasi (paket, class, atau metode) dibatasi sebagai berikut.

Subclass

Gunakan format anotasi @RestrictTo(RestrictTo.Scope.SUBCLASSES) untuk membatasi akses API ke subclass saja.

Hanya class yang memperluas class teranotasi yang dapat mengakses API ini. Modifier protected Java tidak cukup ketat karena masih memungkinkan akses dari class yang tidak terkait dalam paket yang sama. Selain itu, ada kemungkinan Anda ingin membiarkan sebuah metode tetap public demi fleksibilitas di masa mendatang. Metode yang sebelumnya protected dan diganti tidak dapat diubah menjadi public. Tetapi Anda dapat memberikan petunjuk bahwa class tersebut dimaksudkan untuk penggunaan dalam class itu atau dari subclass tertentu saja.

Library

Gunakan format anotasi @RestrictTo(RestrictTo.Scope.GROUP_ID) untuk membatasi akses API hanya ke library Anda.

Hanya kode library Anda yang dapat mengakses API teranotasi. Dengan begitu, Anda tidak hanya dapat menyusun kode dalam hierarki paket apa pun yang diinginkan, tetapi juga membagikan kode di antara sekumpulan library yang terkait. Opsi ini sudah tersedia untuk support library yang memiliki banyak kode implementasi yang tidak dimaksudkan untuk penggunaan eksternal, tetapi library tersebut harus public agar dapat dibagikan ke berbagai support library pelengkap.

Catatan: Class dan paket Android Support Library sekarang dianotasi dengan @RestrictTo(GROUP_ID); artinya, jika Anda tidak sengaja menggunakan class implementasi ini, lint akan memperingatkan Anda bahwa hal tersebut tidak disarankan.

Pengujian

Gunakan format anotasi @RestrictTo(RestrictTo.Scope.TESTS) untuk mencegah developer lain mengakses API pengujian Anda.

Hanya kode pengujian yang dapat mengakses API teranotasi. Anotasi ini mencegah developer lain menggunakan API Anda untuk keperluan pengembangan, sementara Anda menyediakannya untuk keperluan pengujian saja.