Pengantar Komponen Arsitektur Android
() translation by (you can also view the original English article)
Android diperkenalkan ke dunia pada tahun 2005, dan selama 12 tahun keberadaannya, platform tersebut telah mencapai kesuksesan yang luar biasa, menjadi OS mobile yang paling banyak dipasang. Selama waktu itu, 14 versi berbeda dari sistem operasi telah ada diluncurkan, dengan Android selalu menjadi lebih matang. Namun, area yang sangat penting dari platform terus diabaikan: pola arsitektur standar, yang mampu menangani kekhasan platform dan cukup sederhana untuk dipahami dan diadopsi oleh pengembang menengah.
Nah, lebih baik terlambat daripada tidak pernah. Pada Google I/O terakhir, tim Android akhirnya memutuskan untuk mengatasi masalah ini dan menanggapi umpan balik dari pengembang di seluruh dunia, mengumumkan rekomendasi resmi untuk Arsitektur Aplikasi Android dan memberikan blok bangunan untuk menerapkannya: komponen Arsitektur baru Dan lebih baik lagi, mereka berhasil melakukannya tanpa mengorbankan keterbukaan sistem yang kita semua kenal dan cintai.



Dalam tutorial ini, kita akan mengeksplorasi arsitektur standar yang diusulkan oleh tim Android di Google I/O dan melihat elemen utama dari Komponen Arsitektur yang baru: Lifecycle
, ViewModel
, LifeData
, dan Room
. Kami tidak akan terlalu memperhatikan kode tersebut, tapi fokus pada konsep dan logika dibalik tema tersebut. Kami juga akan melihat beberapa cuplikan sederhana, semuanya ditulis menggunakan Kotlin, bahasa yang menakjubkan yang sekarang didukung secara resmi oleh Android.
1. Apa itu Android hilang?
Jika Anda baru saja memulai perjalanan anda sebagai pengembang, ada kemungkinan anda tidak tahu persis apa yang sedang saya bicarakan. Bagaimanapun, arsitektur aplikasi bisa menjadi tema yang tidak jelas pada awalnya. Tapi percayalah, anda akan segera mempelajari kepentingannya! Seiring aplikasi tumbuh dan menjadi lebih kompleks, arsitekturnya akan menjadi semakin penting. Ini benar-benar bisa membuat karya anda menjadi kebahagiaan atau situasi yang sangat tidak menyenangkan
Arsitektur Aplikasi
Menempatkannya secara kira-kira, arsitektur aplikasi adalah rencana yang konsisten yang perlu dibuat sebelum proses pembangunan dimulai. Rencana ini menyediakan peta bagaimana komponen aplikasi yang berbeda harus diatur dan diikat bersama. Ia menyajikan panduan yang harus diikuti selama proses pengembangan dan memaksa beberapa pengorbanan (umumnya terkait dengan kelas dan boilerplate) yang pada akhirnya akan membantu anda membangun aplikasi yang ditulis dengan baik yang lebih dapat diuji, dapat diperluas, dan dapat dipertahankan.
Arsitektur aplikasi perangkat lunak adalah proses untuk menentukan solusi terstruktur yang memenuhi semua persyaratan teknis dan operasional, ketika mengoptimalkan atribut kualitas umum seperti kinerja, keamanan, dan pengelolaan. Ia melibatkan serangkaian keputusan berdasarkan berbagai faktor, dan masing-masing keputusan ini dapat berdampak besar terhadap kualitas, kinerja, kemampuan pemeliharaan, dan keberhasilan aplikasi secara keseluruhan.
- Panduan Desain dan Arsitektur Perangkat Lunak Microsoft
Arsitektur yang baik membutuhkan banyak faktor untuk dipertimbangkan, terutama karakteristik dan batasan sistem. Ada banyak solusi arsitektur yang berbeda di luar sana, semuanya dengan pro dan kontra. Namun, beberapa konsep kunci bersifat umum di antara semua penglihatan.
Kesalahan lama
Sampai Google I/O terakhir, sistem Android tidak merekomendasikan Arsitektur khusus untuk pengembangan aplikasi. Itu berarti anda benar-benar bebas untuk mengadopsi model apapun di luar sana: MVP, MVC, MVPP, atau bahkan tidak ada pola sama sekali. Selain itu, kerangka kerja Android bahkan tidak memberikan solusi asli untuk masalah yang diciptakan oleh sistem itu sendiri, khususnya siklus hidup komponen.



Jadi, jika anda ingin menerapkan pola Model View Presenter pada aplikasi anda, anda harus menemukan solusi anda sendiri dari nol, menulis banyak kode boilerplate, atau mengadopsi perpustakaan tanpa dukungan resmi. Dan bahwa tidak adanya standar yang diciptakan banyak aplikasi yang ditulis dengan buruk, dengan codebases yang sulit untuk mempertahankan dan uji.
Seperti yang saya katakan, situasi ini telah dikritik selama bertahun-tahun. Sebenarnya, saya baru saja menulis tentang masalah ini dan bagaimana mengatasinya di blog saya seri Cara Mengadopsi Model View Presenter di Android. Tapi yang penting adalah bahwa setelah 12 tahun yang panjang, tim Android akhirnya memutuskan untuk mendengarkan keluhan kami dan membantu kami mengatasi masalah ini.
2. Arsitektur Android
Panduan Arsitektur Android baru mendefinisikan beberapa prinsip kunci bahwa aplikasi android yang baik harus sesuai dan juga mengusulkan jalan yang aman bagi pengembang untuk membuat aplikasi yang bagus. Namun, panduan tersebut secara eksplisit menyatakan bahwa rute yang diajukan tidak wajib, dan akhirnya keputusannya bersifat pribadi; pengembang yang harus memutuskan mana jenis arsitektur yang harus diadopsi.
Menurut panduan, aplikasi Android yang bagus harus memberikan pemisahan keprihatinan solid dan drive UI dari model. Setiap kode yang tidak menangani UI atau interaksi sistem operasi seharusnya tidak berada dalam Aktivitas atau Fragmen, karena menjaga mereka agar tetap bersih akan memungkinkan anda menghindari banyak masalah terkait siklus hidup. Lagipula, sistem dapat menghancurkan Aktivitas atau Fragmen kapan saja. Selain itu, data harus ditangani oleh model yang diisolasi dari UI, dan akibatnya dari masalah lifecycle.
Arsitektur Baru yang Disarankan
Arsitektur yang direkomendasikan Android tidak bisa dengan mudah dicap di antara pola standar yang kita kenal. Ini terlihat seperti pola Model View Controller, namun sangat terkait erat dengan arsitektur sistem sehingga sulit memberi label pada setiap elemen menggunakan konvensi yang diketahui. Ini tidak relevan, karena yang terpenting adalah mengandalkan Komponen Arsitektur baru untuk menciptakan pemisahan perhatian, dengan kemampuan testability dan maintainability yang bagus. Dan lebih baik lagi, mudah untuk diimplementasikan.
Untuk memahami apa yang tim Android usulkan, kita harus mengetahui semua elemen Komponen Arsitektur, karena merekalah yang akan melakukan pengangkatan berat bagi kita. Ada empat komponen, masing-masing dengan peran spesifik Room
, ViewModel
, LiveData
, dan Lifecycle
. Semua bagian itu ada tanggung jawab sendiri, dan mereka bekerja sama untuk menciptakan arsitektur yang kokoh. Mari kita lihat diagram yang disederhanakan dari arsitektur yang diusulkan untuk lebih memahaminya.



Seperti yang bisa Anda lihat, kami memiliki tiga elemen utama, masing-masing memiliki tanggung jawab.
-
Activity
danFragment
mewakiliView
layer, yang tidak berhubungan dengan logika bisnis dan operasi yang kompleks. Ia hanya mengonfigurasi tampilan, menangani interaksi pengguna, dan yang terpenting, pengamatan dan menunjukkan elemenLiveData
yang diambil dariViewModel
-
ViewModel
secara otomatis mengamati keadaan tampilanLifecycle
, menjaga konsistensi selama perubahan konfigurasi dan lifecycle events Android lainnya. Hal ini juga dituntut oleh tampilan untuk mengambil data dariRepository
, yang disediakan sebagaiLiveData
yang dapat diamati. Penting untuk dipahami bahwaViewModel
tak pernah merujukView
secara langsung dan update data selalu dilakukan olehLiveData
kesatuan. -
Repository
bukan komponen Android khusus. Ia adalah kelas sederhana, tanpa implementasi tertentu, yang bertanggung jawab untuk mengambil data dari semua sumber yang tersedia, dari database ke layanan web. Ia menangani semua data ini, umumnya mengubahnya menjadiLiveData
yang tampak dan membuat mereka tersedia untukViewModel
. - Database
Room
adalah perpustakaan pemetaan SQLite yang memfasilitasi proses berurusan dengan database. Secara otomatis ia menulis satu ton boilerplate, memeriksa kesalahan pada waktu kompilasi, dan yang terbaik, ia dapat langsung mengembalikan kueri denganLiveData
yang tampak.
Saya yakin anda telah memperhatikan bahwa kami telah banyak membicarakan hal-hal yang dapat diamati. Pola Pengamat adalah salah satu dasar dari elemen LiveData
dan komponen sadar Lifecycle
. Pola ini memungkinkan suatu objek untuk memberi tahu daftar pengamat tentang perubahan pada status atau data. Jadi ketika sebuah Activity mengamati entitas LiveData
, ia akan menerima update saat data tersebut mengalami modifikasi.
Rekomendasi Android lainnya adalah mengkonsolidasikan arsitekturnya menggunakan sistem Dependency Injection, seperti Google Dagger 2 atau menggunakan pola Service Locator (yang jauh lebih sederhana daripada DI, tapi tanpa banyak keuntungannya). Kami tidak akan membahas DI atau Service Locator dalam tutorial ini, namun Envato Tuts + memiliki beberapa tutorial bagus tentang tema tersebut. Namun, maklum bahwa ada beberapa kekhilafan bekerja dengan Dagger 2 dan Android Components yang akan dijelaskan di bagian kedua dari seri ini.
3. Komponen arsitektur
Kita harus terjun jauh ke dalam aspek komponen baru agar bisa benar-benar mengerti dan mengadopsi Model arsitektur ini. Namun, kami tidak akan membahas semua detail dalam tutorial ini. Karena kompleksitas masing-masing elemen, dalam tutorial ini, kita hanya akan membicarakan gagasan umum di balik masing-masing komponen dan melihat beberapa cuplikan kode yang disederhanakan. Kami akan mencoba untuk menyajikan komponen dan membuat anda memulainya. Tapi jangan takut, karena artikel kedepannya di seri ini akan menggali lebih jauh dan mencakup semua kekhasan Komponen Arsitektur.
Komponen Lifecycle-Aware
Sebagian besar komponen aplikasi Android membuat lifecycles melekat padanya, yang dikelola secara langsung oleh sistem itu sendiri. Sampai saat ini, semua terserah pada pengembang untuk memantau keadaan komponen dan bertindak sesuai dengannya, menginisialisasi dan berakhir tugas pada waktu yang tepat. Namun, sangat mudah untuk menjadi bingung dan membuat kesalahan terkait dengan jenis operasi ini. Tetapi paket android.arch.lifecycle
mengubah semua itu.
Sekarang, Aktivitas dan Fragmen membuat objek Lifecycle
melekat pada mereka yang dapat diamati oleh kelas LifecycleObserver
, seperti ViewModel
atau objek yang mengimplementasikan interface ini. Itu berarti pengamat akan menerima pembaruan tentang perubahan keadaan objek yang dilihatnya, seperti saat Aktivitas dihentikan sementara atau saat dimulai. Ia juga dapat memeriksa keadaan objek yang diamati saat ini. Jadi sekarang lebih mudah menangani operasi yang harus mempertimbangkan kerangka kerja lifecycles.



Untuk saat ini, membuat Activity
atau Fragment
yang sesuai dengan standar baru ini, anda harus memperpanjang LifecycleActivity
atau LifecycleFragment
. Namun, mungkin saja hal ini tidak akan selalu diperlukan, karena tim Android bertujuan mengintegrasikan sepenuhnya alat baru ini dengan kerangka kerjanya..
1 |
class MainActivity : LifecycleActivity() { |
2 |
|
3 |
override fun onCreate(savedInstanceState: Bundle?) { |
4 |
super.onCreate(savedInstanceState) |
5 |
setContentView(R.layout.activity_main) |
6 |
} |
7 |
} |
LifecycleObserver
menerima event Lifecycle
dan bisa bereaksi melalui anotasi. Tidak ada metode override yang diperlukan.
1 |
class MainActivityObserver : LifecycleObserver, AnkoLogger { |
2 |
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) |
3 |
fun onResume() { |
4 |
info("onResume") |
5 |
} |
6 |
|
7 |
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) |
8 |
fun onPause() { |
9 |
info("onPause") |
10 |
} |
11 |
} |
Komponen LiveData
Komponen LiveData
adalah dudukan data yang berisi nilai yang tampak. Mengingat bahwa pengamat telah menyediakan Lifecycle
selama Instansiasi LiveData
, LiveData
akan berperilaku menurut status Lifecycle
. Jika pengamat status Lifecycle
DIMULAI
atau DILANJUTKAN
, pengamat menjadi aktif
; Jika tidak, tidak akan aktif
.
LiveData
mengetahui kapan data itu berubah dan juga jika pengamatnya aktif
dan harus menerima update. Karakteristik lain yang menarik dari LiveData
adalah bahwa ia mampu menghapus pengamat jika ia berada di Lifecycle.State.DESTROYED
state, hindari kebocoran memori saat diamati oleh Activities dan Fragments.



LiveData
harus menerapkan metode onActive
dan onInactive
.
1 |
class LocationLiveData(context: Context) |
2 |
: LiveData<Location>(), AnkoLogger, LocationListener { |
3 |
private val locationManager: LocationManager = |
4 |
context.getSystemService(Context.LOCATION_SERVICE) as LocationManager |
5 |
|
6 |
override fun onActive() { |
7 |
info("onActive") |
8 |
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this) |
9 |
} |
10 |
|
11 |
override fun onInactive() { |
12 |
info("onInactive") |
13 |
locationManager.removeUpdates(this) |
14 |
} |
15 |
// .... |
16 |
} |
Untuk mengamati komponen LiveData
, anda harus memanggil observer(LifecycleOwner,Observer<T>)
1 |
class MainActivity : LifecycleActivity(), AnkoLogger { |
2 |
fun observeLocation() { |
3 |
val location = LocationLiveData(this) |
4 |
location.observe(this, |
5 |
Observer { location -> |
6 |
info("location: $location") |
7 |
}) |
8 |
} |
9 |
} |
Komponen ViewModel
Salah satu kelas terpenting dari Komponen Arsitektur yang baru adalah ViewModel
, yang dirancang untuk menyimpan data yang berhubungan dengan UI, menjaga integritas selama perubahan konfigurasi seperti rotasi layar. ViewModel
mampu berbicara dengan Repository
, mendapatkan LiveData
darinya dan membuatnya tersedia pada gilirannya untuk diamati oleh View. ViewModel
juga tidak perlu melakukan panggilan baru ke Repositori
setelah perubahan konfigurasi, yang mengoptimalkan kode banyak



Untuk membuat model tampilan, rentangkan kelas ViewModel
.
1 |
class MainActivityViewModel : ViewModel() { |
2 |
|
3 |
private var notes: MutableLiveData<List<String>>? = null |
4 |
fun getNotes(): LiveData<List<String>> { |
5 |
if (notes == null) { |
6 |
notes = MutableLiveData<List<String>>() |
7 |
loadNotes() |
8 |
} |
9 |
return notes!! |
10 |
} |
11 |
private fun loadNotes() { |
12 |
// do async operation to fetch notes |
13 |
} |
14 |
} |
Untuk mengakses dari suatu tampilan, Anda dapat memanggil ViewProviders.of(Activity|Fragment).get(ViewModel::class.Metode
pabrik ini akan mengembalikan contoh baru ViewModel
atau dapatkan yang ada, jika sesuai.
1 |
class MainActivity : LifecycleActivity(), AnkoLogger { |
2 |
override fun onCreate(savedInstanceState: Bundle?) { |
3 |
super.onCreate(savedInstanceState) |
4 |
setContentView(R.layout.activity_main) |
5 |
|
6 |
val viewModel = ViewModelProviders.of(this) |
7 |
.get(MainActivityViewModel::class.java) |
8 |
viewModel.getNotes().observe( |
9 |
this, Observer { |
10 |
notes -> info("notes: $notes") |
11 |
} |
12 |
) |
13 |
} |
14 |
} |
Komponen Room
Android medukung SQLite sejak awal; Namun, untuk membuatnya bekerja, selalu perlu menulis banyak boilerplate. Juga, SQLite tidak menyimpan POJO (plain-old Java objects), dan tidak memeriksa kueri pada waktu kompilasi. Seiring datang Room
untuk memecahkan masalah ini! Ini adalah perpustakaan pemetaan SQLite, yang mampu menahan POJO Jawa, langsung mengubah kueri ke objek, memeriksa kesalahan pada waktu kompilasi, dan memproduksi LiveData
observables dari hasil query. Room
adalah perpustakaan Object Relational Mapping dengan beberapa tambahan Android yang keren.
Sampai sekarang, anda bisa melakukan sebagian besar dari kemapuam Room
dalam menggunakan library ORM Android lainnya. Namun, tidak satupun dari mereka secara resmi didukung dan yang terpenting, mereka tidak dapat memproduksikan hasil LifeData
. Room
library cocok sebagai lapisan gigih pada Arsitektur Android yang diusulkan.
Untuk membuat database Room
, anda memerlukan sebuah @Entity
untuk bertahan, yang bisa berupa POJO Java, @Dao
interface untuk membuat query dan operasi input/output, dan kelas abstrak @Database
yang harus diperluas RoomDatabase
.
1 |
@Entity |
2 |
class Note { |
3 |
@PrimaryKey |
4 |
var id: Long? = null |
5 |
var text: String? = null |
6 |
var date: Long? = null |
7 |
} |
1 |
@Dao |
2 |
interface NoteDAO { |
3 |
@Insert( onConflict = OnConflictStrategy.REPLACE ) |
4 |
fun insertNote(note: Note): Long |
5 |
|
6 |
@Update( onConflict = OnConflictStrategy.REPLACE ) |
7 |
fun updateNote(note: Note): Int |
8 |
|
9 |
@Delete |
10 |
fun deleteNote(note: Note): Int |
11 |
|
12 |
@Query("SELECT * FROM note") |
13 |
fun findAllNotes(): LiveData<Note> |
14 |
|
15 |
// on Kotlin the query arguments are renamed |
16 |
// to arg[N], being N the argument number. |
17 |
// on Java the arguments assume its original name |
18 |
@Query("SELECT * FROM note WHERE id = :arg0") |
19 |
fun findNoteById(id: Long): LiveData<Note> |
20 |
} |
1 |
@Database( entities = arrayOf(Note::class), version = 1) |
2 |
abstract class Databse : RoomDatabase() { |
3 |
abstract fun noteDAO(): NoteDAO |
4 |
} |
Menambahkan Komponen Arsitektur ke Proyek Anda
Untuk saat ini, untuk menggunakan Komponen Arsitektur yang baru, anda harus terlebih dahulu menambahkan repositori Google ke blog build.gradle
file. anda. Untuk lebih jelasnya, lihat panduan resmi .
1 |
allprojects { |
2 |
repositories { |
3 |
jcenter() |
4 |
// Add Google repository |
5 |
maven { url 'https://maven.google.com' } |
6 |
} |
7 |
} |
Kesimpulan
Seperti yang bisa anda lihat, arsitektur standar yang diusulkan oleh Android melibatkan banyak konsep. Jangan berharap untuk memiliki pemahaman yang lengkap tentang topik ini. Bagaimanapun, kami hanya mengenalkan temanya. Tapi sekarang anda sudah memiliki pengetahuan yang cukup untuk memahami logika di balik arsitektur dan peran Komponen Arsitektur yang berbeda.
Kami membicarakan sebagian besar topik yang terkait dengan arsitektur Android yang diajukan dan komponennya; Namun, rincian tentang penerapan Komponen dan beberapa tambahan, seperti kelas Repository
dan sistem Dagger 2 tidak dapat ditangani oleh bagian pertama ini. Kami akan mengeksplorasi tema tersebut di posting berikutnya.
Sampai jumpa lagi!