Да ли још увек користите АсинцТаск у својим Андроид апликацијама? Вероватно више не би требало да будеш. Ево како да их замените Котлиновим корутинама.
Веома дуго времена у Андроиду, ако сте морали да радите било шта асинхроно када правите апликацију, вероватно бисте користили АсинцТаск. АсинцТаск је АПИ у Андроид оквиру који олакшава (исх) покретање операција у позадини и враћа вредности када се заврши. И то има смисла. За разлику од Котлин Цороутинес, АсинцТаск постоји већ неко време и уграђен је.
Међутим, и филозофија дизајна и имплементација АсинцТаск-а су током година помало застарели. Због тога Гугл има застарели АсинцТаск АПИ. И даље можете да га користите ако желите, али Гоогле не препоручује да то радите. Срећом, постоји читава гомила алтернатива за АсинцТаск, укључујући карактеристике Котлин језика — корутине.
Котлинов АПИ за корутине је невероватно моћан оквир који вам омогућава да урадите гомилу ствари. Овај чланак ће само загребати површину онога што је могуће. Проћи ћемо преко основа потребних за миграцију са АсинцТаск-а на корутине.
Додавање подршке за корутине
Пре него што почнете да користите корутине, морате их заправо додати свом пројекту.
Додавање подршке за Котлин
Ако већ имате имплементиран Котлин, пређите на следећи одељак. У супротном, мораћете да додате Котлин подршку свом пројекту. Погледајте мој водич о додавању Котлина постојећем пројекту за више детаља.
Додавање корутинских библиотека
На нивоу вашег модула build.gradle
, укључују следеће зависности.
dependencies {
...
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-core: 1.5.0'
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-android: 1.5.0'
}
Синхронизујте свој пројекат и Котлинове корутине ће сада бити доступне за коришћење.
Коришћење корутина
Имплементација ЦороутинеСцопе
Да бисте користили корутине, мораћете да имате доступну инстанцу ЦороутинеСцопе. Једноставан начин да то урадите је да га једноставно имплементирате у класу која садржи.
На пример, да бисте имплементирали ЦороутинеСцопе у активност:
classSomeActivity : AppCompatActivity, CoroutineScope by MainScope() {
...
override fun onDestroy(){
super.onDestroy()
cancel()
}
}
Ово ће учинити да СомеАцтивити имплементира интерфејс ЦороутинеСцопе путем класе МаинСцопе. МаинСцопе ће обрадити сву логику имплементације за ЦороутинеСцопе, док вам омогућава да користите ЦороутинеСцопе методе. Зове cancel()
ин onDestroy()
осигурава да ниједна асинхрона логика не настави да ради након што активност изађе.
Замена АсинцТаск-а са корутинама
Рецимо да имате АсинцТаск унутар активности која обавља дуготрајну операцију у позадини и на крају враћа стринг. Нешто попут следећег.
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
}
}
Лако је заменити ово корутином. Само користите async()
методом. Котлин'с async()
ради на било којој нити на којој је покренут, али то ради асинхроно. То значи да можете ажурирати Виевс и слично без бриге о коришћењу праве нити.
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"
}
}
}
Као што видите, коришћење корутина може бити много једноставније него коришћење АсинцТаск-а. Не морате само да зовете async()
и нека то ипак уради своје. Можете задржати референцу на то и чак чекати да се заврши.
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()
Враћање вредности са асинц
Можете чак и да вратите вредност из async()
ако желиш. Дакле, оригинални пример би могао постати овако нешто.
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
}
}
Коришћење витхЦонтект
За практичност, Котлин пружа withContext()
. Ово уграђује целину await()
ствар и само вам враћа вредност.
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
}
}
Закључак
Горе наведени примери су само неке основне употребе Котлин-ових корутина да бисте започели. Не морате да ограничавате корутине на активности или чак било шта са одговарајућим животним циклусом. Можете их покренути у основи било где. Постоје и напредније операције, као што је избор који Тхреад треба да покреће асинхрону логику. Овај водич је углавном за показивање како да замените једноставан АсинцТаск једноставном корутином.
За више детаља о томе како функционишу корутине и како можете да искористите њихове напредније функције, погледајте званична документација Котлина.