Jak zamienić AsyncTask na Coroutines Kotlina

click fraud protection

Czy nadal używasz AsyncTask w swoich aplikacjach na Androida? Prawdopodobnie nie powinieneś już nim być. Oto jak zastąpić je Coroutines Kotlina.

Jeśli przez bardzo długi czas w systemie Android musiałeś zrobić coś asynchronicznie podczas tworzenia aplikacji, prawdopodobnie korzystałbyś z AsyncTask. AsyncTask to interfejs API w środowisku Androida, który ułatwia (w miarę) uruchamianie operacji w tle i zwracanie wartości po zakończeniu. I to ma sens. W przeciwieństwie do Coroutines Kotlina, AsyncTask istnieje już od jakiegoś czasu i jest wbudowany.

Jednak zarówno filozofia projektowania, jak i implementacja AsyncTask stały się z biegiem lat nieco przestarzałe. Z tego powodu Google ma przestarzały interfejs API AsyncTask. Nadal możesz z niego korzystać, jeśli chcesz, ale Google nie zaleca tego. Na szczęście istnieje cała gama alternatyw dla AsyncTask, w tym funkcja języka Kotlin — współprogramy.

Interfejs API współprogramów Kotlina to niezwykle potężny framework, który pozwala robić całą masę rzeczy. Ten artykuł ma na celu jedynie zarysowanie powierzchni tego, co jest możliwe. Omówimy podstawy potrzebne do migracji z AsyncTask do współprogramów.

Dodawanie obsługi współprogramów

Zanim zaczniesz używać współprogramów, musisz je dodać do swojego projektu.

Dodanie obsługi Kotlina

Jeśli masz już zaimplementowany Kotlin, przejdź do następnej sekcji. W przeciwnym razie będziesz musiał dodać obsługę Kotlina do swojego projektu. Więcej szczegółów znajdziesz w moim samouczku na temat dodawania Kotlina do istniejącego projektu.

Dodawanie bibliotek Coroutine

Na poziomie modułu build.gradle, uwzględnij następujące zależności.

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

Zsynchronizuj swój projekt, a współprogramy Kotlina będą teraz dostępne do użycia.

Korzystanie z współprogramów

Implementowanie CoroutineScope

Aby używać współprogramów, musisz mieć dostępną instancję CoroutineScope. Łatwym sposobem na osiągnięcie tego jest po prostu zaimplementowanie go w klasie zawierającej.

Na przykład, aby zaimplementować CoroutineScope w działaniu:

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

override fun onDestroy(){
super.onDestroy()

cancel()
}
}

Spowoduje to, że SomeActivity zaimplementuje interfejs CoroutineScope za pomocą klasy MainScope. MainScope obsłuży całą logikę implementacji dla CoroutineScope, umożliwiając jednocześnie korzystanie z metod CoroutineScope. Powołanie cancel() W onDestroy() upewnia się, że po zakończeniu działania nie będzie kontynuowana żadna logika asynchroniczna.

Zastępowanie AsyncTask współprogramami

Załóżmy, że masz AsyncTask wewnątrz działania, które wykonuje długotrwałą operację w tle i ostatecznie zwraca ciąg znaków. Coś takiego jak poniżej.

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
}
}

Zastąpienie tego współprogramem jest łatwe. Po prostu skorzystaj z async() metoda. Kotlina async() działa na dowolnym wątku, w którym został uruchomiony, ale robi to asynchronicznie. Oznacza to, że możesz aktualizować widoki i tym podobne, nie martwiąc się o użycie odpowiedniego wątku.

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"
}
}
}

Jak widać, używanie współprogramów może być dużo prostsze niż używanie AsyncTask. Nie musisz po prostu dzwonić async() i niech jednak robi swoje. Możesz zachować odniesienie do niego, a nawet poczekać, aż się skończy.

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()

Zwracanie wartości z asynchronią

Możesz nawet zwrócić wartość z async() Jeśli chcesz. Zatem oryginalny przykład mógłby wyglądać mniej więcej tak.

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
}
}

Używanie z kontekstem

Dla wygody Kotlin zapewnia withContext(). To podkreśla całość await() rzecz i po prostu zwraca ci wartość.

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
}
}

Wniosek

Powyższe przykłady to tylko podstawowe zastosowania współprogramów Kotlina, które pomogą Ci zacząć. Nie musisz ograniczać współprogramów do działań ani nawet niczego o odpowiednim cyklu życia. Można je uruchomić w zasadzie wszędzie. Istnieją również bardziej zaawansowane operacje, takie jak wybór wątku, który powinien uruchamiać logikę asynchroniczną. Ten przewodnik ma głównie na celu pokazanie, jak zastąpić proste AsyncTask prostą współprogramem.

Aby uzyskać więcej informacji na temat działania współprogramów i korzystania z ich bardziej zaawansowanych funkcji, zapoznaj się z sekcją oficjalna dokumentacja Kotlina.