Bagaimana Cara Menyempurnakan pemeriksaan kode dengan anotasi pada ANDROID STUDIO?

Penggunaan fitur pemeriksaan kode seperti Lint dapat membantu Anda menemukan masalah dan memperbaiki kode, tetapi fitur pemeriksaan hanya bisa menyimpulkan sejauh itu. ID resource Android, misalnya, menggunakan int untuk mengidentifikasi string, grafis, warna, dan jenis resource lainnya, sehingga fitur pemeriksaan tidak bisa membedakan ketika Anda menetapkan resource string saat Anda seharusnya 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 fitur pemeriksaan kode, anotasi dapat membantu Anda mendeteksi masalah, seperti pengecualian pointer nol 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 anotasi dukungan

Library Anotasi Dukungan dipublikasikan di Google Maven Repository. Untuk menambahkan library Anotasi Dukungan 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 di modul library Anda sendiri, anotasi disertakan sebagai bagian dari artefak Android Archive (AAR) dalam format XML di file annotations.zip. Menambahkan dependensi support-annotations tidak memperkenalkan dependensi untuk setiap pengguna downstream 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 Anotasi Dukungan 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 nol, sedangkan @NonNull menunjukkan variabel, parameter, atau nilai kembalian yang tidak boleh bernilai nol.
Misalnya, jika sebuah variabel lokal yang berisi nilai nol diteruskan sebagai parameter ke metode dengan anotasi @NonNull yang terkait ke parameter tersebut, pembuatan kode akan menghasilkan peringatan yang mengindikasikan konflik bukan-nol. Di sisi lain, jika Anda mencoba mereferensikan hasil metode yang ditandai dengan @Nullable, tanpa terlebih dahulu memeriksa apakah hasilnya bernilai nol, peringatan nullness akan dimunculkan. Sebaiknya Anda hanya menggunakan @Nullable dengan nilai kembalian metode jika setiap penggunaan metode ini perlu dipastikan secara eksplisit nilai nol-nya.
Contoh berikut mengaitkan anotasi @NonNull ke parameter context dan attrs untuk memeriksa bahwa nilai parameter yang diteruskan bukanlah nol. Contoh ini juga memeriksa bahwa metode onCreateView() itu sendiri tidak mengembalikan nol: 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:
    import android.support.annotation.NonNull
    ...

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

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 nol
  • Metode yang tidak boleh menghasilkan nilai nol
  • Variabel, seperti kolom, variabel lokal, dan parameter, yang boleh bernilai nol
  • Variabel, seperti kolom, variabel lokal, dan parameter, yang tidak boleh bernilai nol
Selanjutnya, analisis akan otomatis menyisipkan anotasi nol yang sesuai di lokasi yang dideteksi.
Untuk menjalankan analisis nullability di Android Studio, pilih Analyze > Infer Nullity. Android Studio menyisipkan anotasi @Nullable dan @NonNull Android di lokasi yang terdeteksi dalam kode Anda. Setelah menjalankan analisis nol, sebaiknya Anda memverifikasi anotasi yang dimasukkan itu.
Catatan: Saat menambahkan anotasi nullness, fitur pelengkapan otomatis mungkin menyarankan anotasi @Nullable dan @NotNull IntelliJ, bukan anotasi nol Android, dan dapat otomatis mengimpor library yang terkait. Namun, pemeriksa Lint Android Studio hanya mencari anotasi nol Android. Saat memverifikasi anotasi, konfirmasikan bahwa project Anda menggunakan anotasi nol 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 jenis resource yang direferensikan berbeda, misalnya resource R.string.
Sebagai contoh, tambahkan anotasi @StringRes untuk memeriksa bahwa parameter resource berisi referensi R.string, seperti ditunjukkan di sini:
    abstract fun setTitle(@StringRes resId: Int)
    
Selama inspeksi kode, anotasi 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 inspeksi 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 jenis resource R.
Meskipun Anda dapat menggunakan @ColorRes untuk menentukan bahwa 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. Fitur build akan menandai kode yang salah yang meneruskan ID resource warna, seperti android.R.color.black, bukan integer warna, ke metode yang dianotasi.

Anotasi thread

Anotasi thread memeriksa apakah sebuah metode dipanggil dari jenis thread tertentu. Berikut ini adalah anotasi thread yang didukung:
Catatan: Fitur 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 menganotasi hanya 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 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:
    fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }
    
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:
    fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}
    
Anotasi @Size memeriksa ukuran kumpulan atau array, serta panjang string. Anotasi @Size dapat digunakan untuk memverifikasi kualitas berikut:
  • Ukuran minimum (seperti @Size(min=2))
  • Ukuran maksimum (seperti @Size(max=2))
  • Ukuran persis (seperti @Size(2))
  • Angka jika ukuran harus berupa kelipatan (seperti @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:
    fun getLocation(button: View, @Size(min=1) location: IntArray) {
        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 telah memiliki izin permission.SET_WALLPAPERS:
    @RequiresPermission(Manifest.permission.SET_WALLPAPER)
    @Throws(IOException::class)
    abstract fun setWallpaper(bitmap: Bitmap)
    
Contoh ini mengharuskan pemanggil metode copyFile() memiliki izin baca dan tulis ke penyimpanan eksternal:
    @RequiresPermission(allOf = [
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    ])
    fun copyFile(dest: String, source: String) {
        ...
    }
Untuk izin terkait intent, tempatkan persyaratan izin pada kolom string yang menentukan nama tindakan intent:
    @RequiresPermission(android.Manifest.permission.BLUETOOTH)
    const val 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 :
    @RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS))
    @RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS))
    val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")
    

Izin tidak langsung

Jika izin bergantung pada nilai spesifik yang disediakan ke parameter metode, gunakan @RequiresPermissionpada parameter itu sendiri, tanpa mencantumkan izin khusus. Misalnya, metode startActivity(Intent)menggunakan izin tidak langsung pada intent yang diteruskan ke metode:
    abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)
    
Saat Anda menggunakan izin tidak langsung, fitur build akan menjalankan analisis alur data untuk memeriksa apakah argumen yang diteruskan ke metode memiliki anotasi @RequiresPermission. Selanjutnya, fitur akan memberlakukan semua anotasi yang ada dari parameter pada metode itu sendiri. Dalam contoh startActivity(Intent), anotasi dalam 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).
Fitur build mengeluarkan peringatan startActivity(Intent) dari anotasi pada nama tindakan intent yang terkait dalam class Intent:
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    @RequiresPermission(Manifest.permission.CALL_PHONE)
    const val ACTION_CALL = "android.intent.action.CALL"
    
Jika perlu, Anda dapat memasukkan @RequiresPermission sebagai pengganti @RequiresPermission.Readdan/atau @RequiresPermission.Write saat menganotasi 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 nilai hasil atau kembalian dari sebuah metode benar-benar digunakan. Daripada menganotasi setiap metode non-void dengan @CheckResult, tambahkan anotasi ini untuk mengklarifikasi hasil metode yang berpotensi membingungkan. Misalnya, developer Java baru sering keliru menganggap bahwa <String>.trim() menghapus spasi kosong 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 kepada developer sebagai pengganti:
    @CheckResult(suggest = "#enforcePermission(String,int,int,String)")
    abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int
    

Anotasi CallSuper

Gunakan anotasi @CallSuper untuk memvalidasi bahwa metode pengganti memanggil implementasi super untuk metode tersebut. Contoh berikut menganotasi metode onCreate() untuk memastikan bahwa setiap implementasi metode pengganti memanggil super.onCreate():
    @CallSuper
    override fun onCreate(savedInstanceState: Bundle?) {
    }
    

Anotasi Typedef

Gunakan anotasi @IntDef dan @StringDef sehingga Anda bisa membuat anotasi terenumerasi untuk kumpulan integer dan string untuk memvalidasi jenis referensi kode 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, bersama dengan @Retention, menganotasi anotasi baru dan diperlukan agar dapat menentukan jenis yang dienumerasi. Anotasi @Retention(RetentionPolicy.SOURCE) memberi tahu kompiler untuk tidak menyimpan data anotasi terenumasi 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:
    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

    }
    
Saat Anda membuat kode ini, peringatan akan dimunculkan jika parameter mode tidak mereferensikan salah satu konstanta yang ditentukan (NAVIGATION_MODE_STANDARDNAVIGATION_MODE_LIST, atau NAVIGATION_MODE_TABS).
Anda juga dapat menggabungkan @IntDef dengan @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 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 DisplayOptionsdengan daftar konstanta DISPLAY_ yang valid:
    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
    ...
    
Saat Anda membuat kode dengan flag anotasi, peringatan akan dimunculkan jika parameter yang didekorasi atau nilai kembalian tidak mereferensikan pola yang valid.

Mempertahankan anotasi

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 Anda tetap kecil, pertimbangkan perlu tidaknya mempertahankan setiap anotasi @Keep dalam aplikasi. Jika Anda menggunakan refleksi untuk mengakses class atau metode yang dianotasi, gunakan kondisional -if dalam aturan ProGuard, yang menentukan class yang membuat panggilan refleksi.
Untuk informasi selengkapnya tentang cara memperkecil kode dan menentukan kode yang sebaiknya tidak dihapus, lihat Menyusutkan Kode dan Resource Anda.

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 ini jika tidak digunakan untuk membuatnya terlihat selama 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. Pada penentuan 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.
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    fun myMethod() {
        ...
    }
    
Anda juga dapat menentukan @VisibleForTesting(otherwise = VisibleForTesting.NONE) untuk menunjukkan bahwa metode hanya tersedia untuk keperluan 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 kalanya Anda ingin membiarkan metode tetap bersifat public untuk fleksibilitas di masa depan, karena metode yang sebelumnya protected dan diganti (overridden) tidak akan pernah bisa dijadikan public. Namun, Anda harus memberikan petunjuk bahwa class tersebut ditujukan khusus untuk penggunaan dalam class itu atau dari subclass itu saja.

Library

Gunakan format anotasi @RestrictTo(RestrictTo.Scope.GROUP_ID) untuk membatasi akses API ke library Anda saja.
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 terkait. Opsi ini sudah tersedia untuk library dukungan yang memiliki banyak kode implementasi yang tidak dimaksudkan untuk penggunaan eksternal, tetapi harus public agar dapat dibagikan ke berbagai library dukungan pelengkapnya.
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.
sumber: https://developer.android.com/studio/write/annotations
Was this page helpful?

Komentar

Postingan Populer