Kata pengantar
Kotlin Coroutines adalah API asinkron baru yang diluncurkan oleh Kotlin. Bukan solusi terbaik untuk semua masalah, tetapi mudah -mudahan dalam banyak kasus itu akan membuat segalanya sedikit lebih mudah. Di sini saya hanya akan menunjukkan rencana penggunaan khusus perpustakaan ini di Android. Saya tidak akan mengatakan banyak hal di bawah ini, mari kita lihat perkenalan terperinci bersama.
Memperkenalkan Coroutines
// Tambahkan kode berikut di node Android dalam file build.gradle dari aplikasi Kotlin {eksperimental {coroutine 'Enable'}} // Tambahkan dua baris berikut ke implementasi ketergantungan "org.jetbrains.kotlinx: Kotlinx-coroutines-core: 0,20" implementasi "org.jetbrains.Contoh Coroutine Pertama
Biasanya kami memuat gambar ke ImageView, dan tugas pemuatan asinkron adalah sebagai berikut:
Fun LoadBitMapFrommediastore (ImageId: int, ImagesBaseuri: uri): bitmap {val uri = uri.withappendedPath (gambarbaseuri, imageId.tostring ()) return mediastore.images.media.getbitmap (contentResolver, uri)}Metode ini harus dieksekusi di utas latar belakang karena milik operasi IO, yang berarti kita memiliki banyak solusi untuk memulai tugas latar belakang, dan begitu metode ini mengembalikan bitmap, kita perlu menampilkannya di Imageview segera.
imageview.setImageBitMap (bitmap)
Baris kode ini harus dieksekusi di utas utama, jika tidak ia akan macet.
Jika tiga baris kode di atas ditulis bersama, program akan macet atau macet, yang tergantung pada pilihan utas yang masuk akal. Selanjutnya, mari kita lihat bagaimana coroutine menggunakan Kotlin memecahkan masalah ini:
val job = peluncuran (latar belakang) {val uri = uri.withAppendedPath (gambarBaseuri, gambarId.toString ()) val bitmap = mediastore.images.media.getBitMap (ContentResolver, Luncurkan (UI) {imageview.setimageBitMap (bitmap)}}Yang paling penting di sini adalah latar belakang () dan parameter dan UI. Luncurkan () berarti membuat dan memulai coroutine. Parameter latar belakang Coroutinecontext digunakan untuk memastikan eksekusi di utas latar belakang, sehingga untuk memastikan bahwa aplikasi tidak akan macet atau macet. Anda dapat mendeklarasikan Coroutinecontext seperti yang ditunjukkan di bawah ini.
Latar belakang val internal = newFixedThreadPoolContext (2, "BG")
Ini menciptakan konteks baru dan menggunakan dua utas reguler saat menjalankan tugasnya.
Selanjutnya, Luncurkan (UI), yang akan memicu coroutine lain, yang akan dieksekusi di Android
utas utama.
Dapat dibatalkan
Tantangan berikutnya adalah menangani hal -hal yang terkait dengan siklus deklarasi aktivitas. Saat Anda memuat tugas dan meninggalkan aktivitas sebelum selesai dieksekusi, itu akan menyebabkan crash saat memanggil imageView.setImageBitmap(bitmap) , jadi kita perlu membatalkan tugas sebelum meninggalkan aktivitas. Di sini kami menggunakan nilai pengembalian dari metode peluncuran (). Ketika aktivitas memanggil metode Onstop, kita perlu menggunakan pekerjaan untuk membatalkan tugas.
job.cancel ()
Ini seperti menelepon buang saat Anda menggunakan rxJava dan memanggil fungsi cancel saat Anda menggunakan asynctask.
LifecycleObserver
Komponen Arsitektur Android memberi pengembang Android banyak perpustakaan yang kuat, salah satunya adalah API siklus hidup. Ini memberi kita cara mudah untuk mendengarkan siklus hidup kegiatan dan fragmen secara real time. Mari kita tentukan kode untuk digunakan dengan coroutine.
kelas coroutinelifecyclelistener (val ditangguhkan: ditangguhkan <*>): lifecycleobserver {@onlifecycleevent (lifecycle.event.on_destroy) fun cancelcoroutine () {if (! Deferred.iscancelled) {defred.cancel ()}}}}}} {if (!Kami membuat fungsi ekstensi siklus hidup:
fun <t> lifecycleowner.load (loader: () -> t): ditangguhkan <t> {val ditangguhkan = async (konteks = latar belakang, start = coroutinestArt.lazy) {loader ()} return.addobserver (coroutinelifeCycleRistener (Deferred)) Return} Ada terlalu banyak hal baru dalam metode ini, dan saya akan menjelaskannya satu per satu:
Sekarang kita dapat memanggil load() dalam suatu aktivitas atau fragmen dan mengakses anggota siklus hidup dari fungsi itu dan menambahkan coroutinelifecyclelistener kami sebagai pengamat.
Metode pemuatan membutuhkan loader sebagai parameter, mengembalikan tipe umum T. Dalam metode pemuatan, kami memanggil fungsi Coroutine Creator Async () lainnya, yang akan menggunakan konteks coroutine latar belakang untuk menjalankan tugas di utas latar belakang. Perhatikan bahwa metode ini memiliki parameter lain start = coroutinestart.lazy, yang berarti bahwa coroutine tidak akan segera dieksekusi, sampai dipanggil.
Coroutine kemudian akan mengembalikan objek Defered<T> ke penelepon, yang mirip dengan pekerjaan kami sebelumnya, tetapi juga dapat membawa nilai keterlambatan, seperti JavaScript Promise atau Future <T> dalam Java API biasa, dan bahkan lebih baik, ia memiliki metode yang menunggu.
Selanjutnya kita mendefinisikan fungsi ekstensi lain then() , kali ini kita mendefinisikannya di atas Deferen<T> , yang merupakan jenis yang dikembalikan oleh metode beban kita di atas. Ini juga mengambil lambda sebagai parameter, bernama blok, yang mengambil satu objek tipe T sebagai parameternya.
infix fun <t> ditangguhkan <T> .then (blok: (t) -> unit): job {return launch (context = ui) {block ([email protected] ())}} Fungsi ini akan membuat coroutine lain menggunakan fungsi launch() , yang akan berjalan di utas utama kali ini. Lambda (namanya blok) diteruskan ke coroutine ini mengambil nilai objek yang ditangguhkan yang diselesaikan sebagai parameternya. Kami menelepon await() untuk menangguhkan eksekusi coroutine ini sampai objek yang ditangguhkan mengembalikan nilai.
Di sinilah Coroutine menjadi sangat mengesankan. Panggilan untuk await() dilakukan di utas utama, tetapi tidak memblokir eksekusi lebih lanjut dari utas itu. Ini hanya akan menghentikan pelaksanaan fungsi sampai siap, ketika dilanjutkan dan memberikan nilai tertunda ke lambda. Ketika coroutine ditangguhkan, utas utama dapat terus melakukan hal -hal lain. Fungsi menunggu adalah konsep inti dalam coroutine, apa yang menciptakan semuanya begitu ajaib.
Pengamat siklus hidup yang ditambahkan dalam fungsi load() akan membatalkan coroutine pertama setelah memanggil onDestroy() pada aktivitas kami. Ini juga akan menyebabkan coroutine kedua dibatalkan, mencegah block() dipanggil.
Kotlin Coroutine DSL
Sekarang kita memiliki dua fungsi ekstensi dan kelas yang menangani pembatalan coroutine, mari kita lihat bagaimana menggunakannya:
muat {loadbitmapFrommediastore (ImageId, ImageBaseuri)} lalu {imageview.setImageBitMap (it)} Dalam kode di atas, kami meneruskan metode lambda ke fungsi beban, yang memanggil metode LoadBitMapFrommediastore, yang harus dieksekusi pada utas latar belakang sampai metode mengembalikan bitmap, dan nilai pengembalian metode beban Deferred<Bitmap> .
Sebagai fungsi ekstensi, metode then() menggunakan deklarasi infix. Meskipun metode pemuatan yang dikembalikan Deferred<Bitmap> , itu akan diteruskan ke metode kemudian nilai pengembalian bitmap, sehingga kita dapat secara langsung memanggil imageView.setImageBitmap(it) dalam metode kemudian.
Kode di atas dapat digunakan untuk panggilan asinkron yang perlu terjadi pada utas latar belakang, dan di mana nilai pengembalian harus dikembalikan ke utas utama, seperti pada contoh di atas. Itu tidak membuat banyak panggilan seperti yang dilakukan RXJAVA, tetapi lebih mudah dibaca dan dapat mencakup banyak kasus yang paling umum. Sekarang Anda dapat melakukan sesuatu seperti ini dengan aman tanpa khawatir menyebabkan kebocoran konteks atau pemrosesan utas dalam setiap panggilan;
muat {restapi.fetchdata (kueri)} lalu {adapter.display (it)}Metode kemudian () dan muat () hanyalah puncak gunung es dari perpustakaan baru ini, tetapi saya berharap sesuatu yang serupa muncul di perpustakaan Android yang berbasis di Kotlin di masa depan begitu versi Coroutine mencapai versi yang stabil. Sebelum ini Anda dapat menggunakan atau memodifikasi kode di atas, atau periksa Anko Coroutine. Saya juga merilis versi yang lebih lengkap di GitHub. (https://github.com/erikhellman/kotlinasyncwithcoroutines (unduhan lokal)).
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.