Kā aizstāt AsyncTask ar Kotlina korutīnu

Vai joprojām izmantojat AsyncTask savās Android lietotnēs? Tev laikam vairs nevajadzētu būt. Lūk, kā tos aizstāt ar Kotlin's Coroutines.

Ļoti ilgu laiku operētājsistēmā Android, ja, veidojot lietotni, jums kaut kas būtu jādara asinhroni, jūs, iespējams, izmantojāt AsyncTask. AsyncTask ir API Android sistēmā, kas atvieglo darbību veikšanu fonā un vērtību atgriešanu, kad tas ir pabeigts. Un tam ir jēga. Atšķirībā no Kotlin's Coroutines, AsyncTask ir pastāvējis kādu laiku, un tas ir iebūvēts.

Tomēr gan AsyncTask dizaina filozofija, gan ieviešana gadu gaitā ir nedaudz novecojusi. Tāpēc Google ir novecojusi AsyncTask API. Jūs joprojām varat to izmantot, ja vēlaties, taču Google neiesaka to darīt. Par laimi, AsyncTask ir daudz alternatīvu, tostarp Kotlin valodas iezīme - korutīnas.

Kotlin's coroutines API ir neticami spēcīgs ietvars, kas ļauj veikt daudzas lietas. Šis raksts tikai ieskrāpēs visu iespējamo. Mēs apskatīsim pamatus, kas nepieciešami, lai migrētu no AsyncTask uz korutīnu.

Korutīnu atbalsta pievienošana

Lai varētu sākt lietot korutīnas, tās faktiski jāpievieno savam projektam.

Kotlin atbalsta pievienošana

Ja esat jau ieviesis Kotlin, pārejiet uz nākamo sadaļu. Pretējā gadījumā jums būs jāpievieno Kotlin atbalsts savam projektam. Lai iegūtu sīkāku informāciju, skatiet manu pamācību par Kotlin pievienošanu esošam projektam.

Korutīnas bibliotēku pievienošana

Jūsu moduļa līmenī build.gradle, iekļaujiet šādas atkarības.

dependencies {
...
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-core: 1.5.0'
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-android: 1.5.0'
}

Sinhronizējiet savu projektu, un Kotlinas korutīnas tagad būs pieejamas lietošanai.

Korutīnu izmantošana

CoroutineScope ieviešana

Lai izmantotu korutīnas, jums ir jābūt pieejamai CoroutineScope instancei. Vienkāršs veids, kā to izdarīt, ir vienkārši ieviest to savā saturošajā klasē.

Piemēram, lai aktivitātē ieviestu CoroutineScope:

classSomeActivity : AppCompatActivity, CoroutineScope by MainScope() {
...

override fun onDestroy(){
super.onDestroy()

cancel()
}
}

Tas liks SomeActivity ieviest CoroutineScope saskarni, izmantojot MainScope klasi. MainScope apstrādās visu CoroutineScope ieviešanas loģiku, vienlaikus ļaujot izmantot CoroutineScope metodes. Zvana cancel() iekšā onDestroy() nodrošina, ka pēc darbības iziešanas neturpina darboties asinhronā loģika.

AsyncTask aizstāšana ar korutīnu

Pieņemsim, ka aktivitātē ir AsyncTask, kas fonā veic ilgstošu darbību un galu galā atgriež virkni. Kaut kas līdzīgs šim.

private inner classSomeTask : AsyncTask() {
override fun doInBackground(vararg params: Void): String {
try {
//Pretend this is an actual operation that takes 10 seconds and not just sleeping.
Thread.sleep(10000);
} catch (e: InterruptedException) {}

return"SomeString";
}

override fun onPostExecute(result: String) {
val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

To ir viegli aizstāt ar korutīnu. Vienkārši izmantojiet async() metodi. Kotlina async() darbojas jebkurā pavedienā, kurā tas tika palaists, bet to dara asinhroni. Tas nozīmē, ka varat atjaunināt Views un citas lietas, neuztraucoties par pareizā pavediena izmantošanu.

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...

private fun doOperation(){
async {
//Inside coroutine scopes (like inside async here), delay is used instead of Thread.sleep.
delay(10000)

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = "SomeString"
}
}
}

Kā redzat, korutīnu izmantošana var būt daudz vienkāršāka nekā AsyncTask izmantošana. Jums nav vienkārši jāzvana async() un ļaujiet tai darīt savu. Varat turēt atsauci uz to un pat gaidīt, līdz tā beigsies.

val asyncJob = async {
//Some operation
}
//Pause here until the async block is finished.
asyncJob.await()

//This won't run until asyncJob finishes, but other operations started before the job, or started from another method, can still run.
doSomethingElse()

Vērtību atgriešana ar asinhrono

Varat pat atgriezt vērtību no async() Ja tu vēlies. Tātad sākotnējais piemērs varētu kļūt par kaut ko līdzīgu šim.

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...
private fun doOperation(){
val asyncJob = async {
//Inside coroutine scopes (like inside async here), delay is used instead of Thread.sleep.
delay(10000)

//Whatever the type is of the last line is what async() eventually returns.
"SomeString"
}

val result = asyncJob.await()

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

Izmantojot withContext

Ērtības labad Kotlins nodrošina withContext(). Tas iekļauj visumā await() lieta un vienkārši atgriež jums vērtību.

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...
private fun doOperation(){
//Run asynchronously on the main Thread.
val result = withContext(Dispatchers.Main) {
delay(10000)

"SomeResult"
}

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

Secinājums

Iepriekš minētie piemēri ir tikai daži pamata Kotlina korutīnu lietojumi, lai jūs sāktu. Jums nav jāierobežo periodiskās darbības ar aktivitātēm vai pat jebko, kam ir atbilstošs dzīves cikls. Jūs varat tos palaist būtībā jebkur. Ir arī sarežģītākas darbības, piemēram, izvēle, kuram pavedienam vajadzētu palaist asinhrono loģiku. Šī rokasgrāmata galvenokārt ir paredzēta, lai parādītu, kā vienkāršu AsyncTask aizstāt ar vienkāršu korutīnu.

Lai iegūtu papildinformāciju par to, kā darbojas korutīnas un kā varat izmantot to uzlabotās funkcijas, skatiet oficiālā Kotlin dokumentācija.