Konsep dan penerapan Jetpack Compose
Halaman ini menyajikan beberapa praktik terbaik dan rekomendasi arsitektur. Gunakan keduanya untuk meningkatkan kualitas, keandalan, dan skalabilitas aplikasi. Alat ini juga memudahkan pemeliharaan dan pengujian aplikasi Anda.
Lapisan UI
Peran lapisan UI adalah menampilkan data aplikasi di layar dan berfungsi sebagai titik utama interaksi pengguna. Berikut adalah beberapa praktik terbaik untuk lapisan UI:
- Anda harus membuat repositori meskipun hanya berisi satu sumber data.
- Di aplikasi kecil, Anda dapat memilih untuk menempatkan jenis lapisan data dalam paket atau modul
data.
Rekomendasi |
Deskripsi |
Ikuti Aliran Data Searah (UDF). Sangat direkomendasikan |
Ikuti prinsip-prinsip Aliran Data Searah (UDF), dengan ViewModels mengekspos status UI menggunakan pola observer dan menerima tindakan dari UI melalui panggilan metode. |
Gunakan ViewModels AAC jika manfaatnya berlaku untuk aplikasi Anda. Sangat direkomendasikan |
Gunakan ViewModels AAC untuk menangani logika bisnis, dan mengambil data aplikasi untuk mengekspos status UI ke UI. Lihat praktik terbaik ViewModel lainnya di sini. Lihat manfaat ViewModel di sini. |
Gunakan koleksi status UI yang mendukung siklus proses. Sangat direkomendasikan |
Kumpulkan status UI dari UI menggunakan builder coroutine berbasis siklus proses yang sesuai, Baca selengkapnya tentang |
Jangan mengirim peristiwa dari ViewModel ke UI. Sangat direkomendasikan |
Proses peristiwa secara langsung di ViewModel dan menyebabkan pembaruan status dengan hasil penanganan peristiwa. Selengkapnya tentang peristiwa UI di sini. |
Gunakan aplikasi aktivitas tunggal. Direkomendasikan |
Gunakan Navigation Fragment untuk menavigasi antar-layar dan deep link ke aplikasi Anda jika aplikasi memiliki lebih dari satu layar. |
Cuplikan berikut menguraikan cara mengumpulkan status UI dengan cara yang memperhitungkan siklus proses:
class MyFragment : Fragment() {
private val viewModel: MyViewModel by viewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect {
// Process item
}
}
}
}
}
ViewModel
ViewModels bertanggung jawab untuk menyediakan status UI dan akses ke lapisan data. Berikut adalah beberapa praktik terbaik untuk ViewModels:
Rekomendasi |
Deskripsi |
ViewModels seharusnya tidak bergantung pada siklus proses Android. Sangat direkomendasikan |
ViewModel tidak boleh menyimpan referensi ke jenis terkait Siklus Proses. Jangan teruskan |
Gunakan coroutine dan flow. Sangat direkomendasikan |
ViewModel berinteraksi dengan lapisan data atau domain menggunakan:
|
Menggunakan ViewModel pada tingkat layar. Sangat direkomendasikan |
Jangan gunakan ViewModel dalam potongan UI yang dapat digunakan kembali. Anda harus menggunakan ViewModel di:
|
Jangan gunakan Sangat direkomendasikan |
Gunakan class |
Ekspos status UI. Direkomendasikan |
ViewModel harus mengekspos data ke UI melalui satu properti yang disebut
|
Cuplikan berikut menguraikan cara mengekspos status UI dari ViewModel:
@HiltViewModel
class BookmarksViewModel @Inject constructor(
newsRepository: NewsRepository
) : ViewModel() {
val feedState: StateFlow<NewsFeedUiState> =
newsRepository
.getNewsResourcesStream()
.mapToFeedState(savedNewsResourcesState)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = NewsFeedUiState.Loading
)
// ...
}
Siklus Proses
Berikut adalah beberapa praktik terbaik untuk menggunakan siklus proses Android:
Rekomendasi |
Deskripsi |
Jangan mengganti metode siklus proses dalam Activity atau Fragment. Sangat direkomendasikan |
Jangan mengganti metode siklus proses seperti |
Cuplikan berikut menguraikan cara menjalankan operasi dengan status Siklus Proses tertentu:
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
// ...
}
override fun onPause(owner: LifecycleOwner) {
// ...
}
}
}
}