Penggunaan alat pemeriksaan kode seperti lint dapat membantu Anda
menemukan masalah dan meningkatkan kualitas kode, tetapi kemampuan alat pemeriksaan hanya sebatas itu. ID resource Android, misalnya,
menggunakan int
untuk mengidentifikasi string, grafis, warna, dan jenis resource lainnya,
sehingga alat pemeriksaan tidak dapat membedakan ketika 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.
Dengan anotasi, Anda dapat menyediakan petunjuk untuk alat pemeriksaan kode, seperti lint, untuk membantu mendeteksi masalah kode yang sulit dideteksi ini. Anotasi ditambahkan sebagai tag metadata yang dilampirkan ke variabel, parameter, dan nilai yang ditampilkan untuk memeriksa nilai yang ditampilkan 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
Library Jetpack Annotations.
Anda dapat mengakses library ini
melalui paket
androidx.annotation
.
Catatan: Jika ada modul yang memiliki dependensi pada pemroses anotasi,
Anda harus menggunakan konfigurasi dependensi kapt
atau ksp
untuk Kotlin
atau konfigurasi dependensi annotationProcessor
untuk Java guna menambahkan
dependensi tersebut.
Menambahkan anotasi ke project
Untuk mengaktifkan anotasi dalam project Anda, tambahkan
dependensi androidx.annotation:annotation
ke library atau aplikasi Anda. Setiap anotasi yang ditambahkan akan diperiksa saat Anda menjalankan pemeriksaan
kode atau tugas lint
.
Menambahkan dependensi library Jetpack Annotations
Library Jetpack Annotations dipublikasikan
di Repositori Maven Google.
Untuk menambahkan library Jetpack Annotations ke project Anda, sertakan baris
berikut dalam blok dependencies
file build.gradle
atau
build.gradle.kts
:
Kotlin
dependencies { implementation("androidx.annotation:annotation:1.9.1") }
Groovy
dependencies { implementation 'androidx.annotation:annotation:1.9.1' }
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 androidx.annotation
tidak akan memperkenalkan dependensi untuk pengguna downstream
library Anda.
Catatan: Jika menggunakan library Jetpack lainnya,
Anda mungkin tidak perlu menambahkan dependensi androidx.annotation
. Karena banyak library Jetpack
lain bergantung pada Library Annotations, Anda mungkin sudah memiliki akses ke
anotasi tersebut.
Untuk daftar lengkap anotasi yang disertakan dalam repositori Jetpack, lihat
referensi library Jetpack
Annotations atau gunakan fitur pelengkapan otomatis guna menampilkan opsi yang tersedia
untuk pernyataan import androidx.annotation.
.
Menjalankan pemeriksaan kode
Untuk memulai pemeriksaan kode dari Android Studio yang menyertakan validasi anotasi dan pemeriksaan lint otomatis, pilih Analyze > Inspect Code dari menu. Android Studio menampilkan pesan konflik untuk menandai potensi masalah apabila kode Anda bertentangan dengan anotasi dan menyarankan kemungkinan resolusi.
Anda juga dapat menerapkan anotasi dengan menjalankan
tugas lint
menggunakan command line. Meskipun cara ini mungkin berguna untuk menandai masalah
server continuous integration, tugas lint
tidak menerapkan anotasi
nullness (dijelaskan di bagian berikut); hanya Android Studio yang melakukan penerapan ini. Untuk mengetahui informasi
selengkapnya tentang cara mengaktifkan dan menjalankan pemeriksaan
lint, lihat Meningkatkan kualitas kode dengan
lint.
Meskipun konflik anotasi menghasilkan peringatan, peringatan ini tidak mencegah aplikasi Anda melakukan kompilasi.
Anotasi nullness
Anotasi nullness dapat berguna dalam kode Java untuk menerapkan kemungkinan nilai menjadi null. Fungsi ini kurang berguna dalam kode Kotlin karena Kotlin telah membuat aturan nullability yang diterapkan pada waktu kompilasi.Tambahkan anotasi @Nullable
dan
@NonNull
untuk memeriksa
nullness variabel, parameter, atau nilai yang ditampilkan tertentu. Anotasi @Nullable
menunjukkan variabel, parameter, atau nilai yang ditampilkan tertentu yang boleh bernilai null.
@NonNull
menunjukkan variabel, parameter, atau nilai yang ditampilkan yang tidak boleh bernilai null.
Misalnya, jika sebuah variabel lokal yang berisi nilai null diteruskan sebagai parameter ke metode
dengan anotasi @NonNull
yang dilampirkan ke parameter tersebut, pembuatan kode akan menghasilkan
peringatan yang menunjukkan konflik non-null. Selain itu, mencoba merujuk hasil
metode yang ditandai dengan @Nullable
tanpa terlebih dahulu memeriksa apakah hasilnya bernilai null akan menghasilkan
peringatan nullness. Hanya gunakan @Nullable
pada nilai yang ditampilkan metode
jika setiap penggunaan metode ini harus diperiksa secara eksplisit nilai null-nya.
Contoh berikut menunjukkan cara kerja nullability. Kode contoh Kotlin tidak memanfaatkan
anotasi @NonNull
karena akan otomatis ditambahkan ke bytecode yang dihasilkan
saat jenis non-nullable ditentukan. Contoh Java memanfaatkan anotasi @NonNull
pada parameter context
dan attrs
untuk memeriksa bahwa nilai parameter yang diteruskan
bukan null. Contoh ini juga
memeriksa bahwa metode onCreateView()
tersebut tidak menghasilkan null:
Kotlin
... /** Annotation not used because of the safe-call operator(?)**/ override fun onCreateView( name: String?, context: Context, attrs: AttributeSet ): View? { ... } ...
Java
import androidx.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 null.
- Metode yang tidak boleh menghasilkan 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 tersebut.
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,
pastikan 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 untuk merujuk ke jenis resource tertentu, seperti String
,
dapat diteruskan ke jenis referensi int
yang diharapkan, tetapi sebenarnya merujuk ke jenis
resource berbeda, seperti resource R.string
.
Sebagai contoh, tambahkan anotasi @StringRes
untuk
memastikan parameter resource berisi referensi R.string
, seperti yang ditampilkan 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
mendukung beberapa jenis resource, Anda dapat menempatkan lebih dari satu anotasi jenis resource pada 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
parameter harus berupa resource warna, integer warna (dalam format RRGGBB
atau
AARRGGBB
) tidak akan dikenali 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 adalah anotasi thread yang didukung:
Alat build memperlakukan anotasi @MainThread
dan
@UiThread
sebagai dapat dipertukarkan sehingga Anda dapat memanggil metode @UiThread
dari metode @MainThread
, dan sebaliknya. Namun, ada kemungkinan UI thread
berbeda dengan thread utama pada aplikasi sistem yang memiliki beberapa tampilan
dalam thread yang berbeda. Oleh 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 class ini dipanggil dari jenis thread yang sama.
Penggunaan anotasi thread yang umum adalah untuk memvalidasi bahwa metode atau class yang dianotasikan dengan
@WorkerThread
hanya dipanggil dari thread latar belakang yang sesuai.
Anotasi batasan nilai
Gunakan anotasi @IntRange
,
@FloatRange
, dan
@Size
untuk memvalidasi
nilai parameter yang diteruskan. @IntRange
dan @FloatRange
akan sangat berguna jika diterapkan pada parameter dengan rentang yang cenderung sering salah ditetapkan oleh pengguna.
Anotasi @IntRange
memvalidasi bahwa nilai parameter integer atau long
berada dalam rentang yang ditetapkan. Contoh berikut menunjukkan bahwa parameter alpha
harus berisi nilai bilangan bulat antara 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
memastikan bahwa nilai parameter
float atau double berada dalam rentang nilai floating point yang ditetapkan. Contoh berikut menunjukkan bahwa parameter alpha
harus berisi nilai float antara 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,
array, atau panjang string. Anotasi @Size
dapat digunakan untuk memverifikasi
kualitas berikut:
- Ukuran minimum, misalnya
@Size(min=2)
- Ukuran maksimum, misalnya
@Size(max=2)
- Ukuran persis, misalnya
@Size(2)
- Angka dengan ukuran yang harus dalam kelipatan, seperti
@Size(multiple=2)
Misalnya, @Size(min=1)
memastikan kumpulan tidak kosong, dan @Size(3)
memvalidasi bahwa array berisi persis tiga nilai.
Contoh berikut menunjukkan bahwa array
location
harus 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 menunjukkan bahwa pemanggil metode harus 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 berikut mengharuskan pemanggil metode copyImageFile()
memiliki
akses baca ke penyimpanan eksternal dan akses baca ke metadata lokasi
pada gambar yang disalin:
Kotlin
@RequiresPermission(allOf = [ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION ]) fun copyImageFile(dest: String, source: String) { ... }
Java
@RequiresPermission(allOf = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION}) public static final void copyImageFile(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 memerlukan izin terpisah untuk akses baca dan
tulis, gabungkan 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.
Alat build mengeluarkan peringatan tentang startActivity(Intent)
dari anotasi
pada nama tindakan intent yang terkait dalam class Intent
:
Kotlin
@RequiresPermission(Manifest.permission.CALL_PHONE) const val ACTION_CALL = "android.intent.action.CALL"
Java
@RequiresPermission(Manifest.permission.CALL_PHONE) public static final String ACTION_CALL = "android.intent.action.CALL";
Jika perlu, Anda dapat mengganti @RequiresPermission
dengan
@RequiresPermission.Read
atau @RequiresPermission.Write
saat menganotasikan
parameter metode. Namun, untuk izin tidak langsung, @RequiresPermission
tidak boleh
digunakan bersama anotasi izin baca atau 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 kosong dari string asli. Menganotasi
metode dengan @CheckResult
akan menandai penggunaan <String>.trim()
saat pemanggil tidak melakukan apa pun terhadap nilai yang ditampilkan metode.
Contoh berikut menganotasi metode checkPermissions()
untuk memeriksa apakah nilai yang ditampilkan 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
Anotasi Typedef memeriksa apakah parameter, nilai kembali, atau kolom tertentu merujuk ke kumpulan konstanta tertentu. Anotasi ini juga memungkinkan pelengkapan kode untuk otomatis menawarkan konstanta yang diizinkan.
Gunakan anotasi @IntDef
dan
@StringDef
untuk membuat anotasi terenumerasi kumpulan integer dan string untuk memvalidasi jenis
referensi kode lainnya.
Anotasi Typedef menggunakan @interface
untuk mendeklarasikan jenis anotasi terenumerasi yang baru.
Anotasi @IntDef
dan @StringDef
, beserta
@Retention
, menganotasi anotasi baru ini dan diperlukan untuk menentukan
jenis terenumerasi. Anotasi @Retention(RetentionPolicy.SOURCE)
memberi tahu compiler
untuk tidak menyimpan data anotasi terenumerasi dalam file .class
.
Contoh berikut menunjukkan langkah-langkah pembuatan anotasi yang memeriksa apakah suatu nilai diteruskan sebagai parameter metode yang mereferensikan salah satu konstanta yang ditentukan:
Kotlin
import androidx.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 androidx.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 dikeluarkan jika parameter mode
tidak
mereferensikan salah satu konstanta yang ditentukan (NAVIGATION_MODE_STANDARD
,
NAVIGATION_MODE_LIST
, atau NAVIGATION_MODE_TABS
).
Kombinasikan @IntDef
dan @IntRange
untuk menunjukkan bahwa
integer dapat berupa sekumpulan konstanta tertentu atau nilai dalam suatu rentang.
Mengaktifkan penggabungan konstanta dengan tanda
Jika pengguna dapat menggabungkan konstanta yang diizinkan dengan sebuah tanda (misalnya |
,
&
, ^
, dan seterusnya), Anda dapat menetapkan anotasi dengan
atribut flag
untuk memeriksa apakah parameter atau nilai yang ditampilkan merujuk pola yang valid.
Contoh berikut akan membuat anotasi DisplayOptions
dengan daftar konstanta
DISPLAY_
yang valid:
Kotlin
import androidx.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 androidx.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 tanda anotasi, peringatan akan dikeluarkan jika parameter yang didekorasi atau nilai yang ditampilkan tidak merujuk pola yang valid.
Anotasi Keep
Anotasi @Keep
memastikan bahwa class atau metode yang dianotasi tidak dihapus saat kode
diminifikasi 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.
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 mengetahui informasi selengkapnya tentang cara meminifikasi kode dan menentukan kode yang tidak boleh dihapus, lihat Menyingkat, meng-obfuscate, dan mengoptimalkan aplikasi.
Anotasi visibilitas kode
Gunakan anotasi berikut untuk menunjukkan visibilitas bagian kode tertentu, seperti metode, class, kolom, atau paket.
Membuat kode terlihat 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 tidak dimaksudkan untuk membuatnya terlihat
selama pengujian. Lint menggunakan argumen otherwise
untuk memberlakukan visibilitas yang diinginkan.
Dalam contoh berikut, myMethod()
biasanya adalah private
, tetapi anotasi untuk pengujian
adalah package-private
. Dengan penetapan VisibleForTesting.PRIVATE
,
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
metode public
demi fleksibilitas di masa mendatang karena Anda tidak akan pernah dapat membuat protected
sebelumnya dan public
metode yang diganti, tetapi Anda ingin memberikan
petunjuk bahwa class tersebut dimaksudkan untuk penggunaan dalam class itu atau dari subclass tertentu saja.
Library
Gunakan format anotasi @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
untuk
membatasi akses API hanya ke library Anda.
Hanya kode library Anda yang dapat mengakses API teranotasi. Dengan begitu, Anda tidak hanya dapat mengatur kode
dalam hierarki paket apa pun yang diinginkan, tetapi juga membagikan
kode di antara sekumpulan library yang terkait. Opsi ini sudah tersedia untuk library
Jetpack yang memiliki banyak kode implementasi yang tidak dimaksudkan untuk penggunaan eksternal, tetapi library
tersebut harus berupa public
agar dapat dibagikan ke berbagai library Jetpack pelengkap.
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.