Εξακολουθείτε να χρησιμοποιείτε το AsyncTask στις εφαρμογές σας Android; Μάλλον δεν θα έπρεπε να είσαι πια. Δείτε πώς μπορείτε να τα αντικαταστήσετε με τις Κορουτίνες του Κότλιν.
Για πολύ μεγάλο χρονικό διάστημα στο Android, εάν έπρεπε να κάνετε οτιδήποτε ασύγχρονα κατά τη δημιουργία μιας εφαρμογής, πιθανότατα θα χρησιμοποιούσατε το AsyncTask. Το AsyncTask είναι ένα API στο πλαίσιο του Android που διευκολύνει (ish) την εκτέλεση λειτουργιών στο παρασκήνιο και την επιστροφή τιμών όταν τελειώσει. Και αυτό είναι λογικό. Σε αντίθεση με τα Coroutines του Kotlin, το AsyncTask κυκλοφορεί εδώ και λίγο καιρό και είναι ενσωματωμένο.
Ωστόσο, τόσο η φιλοσοφία σχεδιασμού όσο και η εφαρμογή του AsyncTask έχουν γίνει κάπως ξεπερασμένα με τα χρόνια. Εξαιτίας αυτού, η Google έχει καταργήθηκε το AsyncTask API. Μπορείτε ακόμα να το χρησιμοποιήσετε αν θέλετε, αλλά η Google δεν συνιστά να το κάνετε. Ευτυχώς, υπάρχει ένα σωρό εναλλακτικές λύσεις για το AsyncTask, συμπεριλαμβανομένου ενός χαρακτηριστικού της γλώσσας Kotlin - κορουτίνες.
Το Kotlin's coroutines API είναι ένα απίστευτα ισχυρό πλαίσιο που σας επιτρέπει να κάνετε πολλά πράγματα. Αυτό το άρθρο πρόκειται μόνο να χαράξει την επιφάνεια του τι είναι δυνατό. Θα εξετάσουμε τα βασικά που απαιτούνται για τη μετεγκατάσταση από το AsyncTask στις κορουτίνες.
Προσθήκη υποστήριξης Coroutines
Για να μπορέσετε να αρχίσετε να χρησιμοποιείτε κορουτίνες, πρέπει να τις προσθέσετε πραγματικά στο έργο σας.
Προσθήκη υποστήριξης Kotlin
Εάν έχετε ήδη εφαρμόσει το Kotlin, μεταβείτε στην επόμενη ενότητα. Διαφορετικά, θα πρέπει να προσθέσετε υποστήριξη Kotlin στο έργο σας. Δείτε το σεμινάριο μου σχετικά με την προσθήκη του Kotlin σε ένα υπάρχον έργο για περισσότερες λεπτομέρειες.
Προσθήκη Βιβλιοθηκών Κορουτίνας
Στο επίπεδο της ενότητας σας build.gradle
, περιλαμβάνει τις ακόλουθες εξαρτήσεις.
dependencies {
...
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-core: 1.5.0'
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-android: 1.5.0'
}
Συγχρονίστε το έργο σας και οι κορουτίνες του Kotlin θα είναι πλέον διαθέσιμες για χρήση.
Χρήση κορουτινών
Εφαρμογή CoroutineScope
Για να χρησιμοποιήσετε κορουτίνες, θα πρέπει να έχετε διαθέσιμη μια παρουσία CoroutineScope. Ένας εύκολος τρόπος για να το κάνετε αυτό είναι απλώς να το εφαρμόσετε στην κλάση που περιέχει.
Για παράδειγμα, για να εφαρμόσετε ένα CoroutineScope σε μια δραστηριότητα:
classSomeActivity : AppCompatActivity, CoroutineScope by MainScope() {
...
override fun onDestroy(){
super.onDestroy()
cancel()
}
}
Αυτό θα κάνει το SomeActivity να εφαρμόσει τη διεπαφή CoroutineScope μέσω της κλάσης MainScope. Το MainScope θα χειριστεί όλη τη λογική υλοποίησης για το CoroutineScope, ενώ σας επιτρέπει να χρησιμοποιείτε τις μεθόδους CoroutineScope. Κλήση cancel()
σε onDestroy()
διασφαλίζει ότι δεν συνεχίζει να εκτελείται ασύγχρονη λογική μετά την έξοδο από τη Δραστηριότητα.
Αντικατάσταση του AsyncTask με Κορουτίνες
Ας υποθέσουμε ότι έχετε ένα AsyncTask μέσα σε μια δραστηριότητα που εκτελεί μια μακροχρόνια λειτουργία στο παρασκήνιο και τελικά επιστρέφει μια συμβολοσειρά. Κάτι σαν το παρακάτω.
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"
}
}
}
Όπως μπορείτε να δείτε, η χρήση κορουτινών μπορεί να είναι πολύ πιο απλή από τη χρήση του AsyncTask. Δεν χρειάζεται απλά να τηλεφωνήσετε 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
Μπορείτε ακόμη και να επιστρέψετε μια τιμή από 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
Για ευκολία, το Kotlin παρέχει 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
}
}
συμπέρασμα
Τα παραπάνω παραδείγματα είναι μόνο μερικές βασικές χρήσεις των κορουτινών του Κότλιν για να ξεκινήσετε. Δεν χρειάζεται να περιορίσετε τις κορουτίνες σε Δραστηριότητες ή ακόμα και οτιδήποτε με σωστό κύκλο ζωής. Μπορείτε να τα εκτελέσετε βασικά οπουδήποτε. Υπάρχουν επίσης πιο προηγμένες λειτουργίες, όπως η επιλογή του Thread που θα εκτελεί την ασύγχρονη λογική. Αυτός ο οδηγός είναι κυρίως για να δείξει πώς να αντικαταστήσετε ένα απλό AsyncTask με μια απλή κορουτίνα.
Για περισσότερες λεπτομέρειες σχετικά με το πώς λειτουργούν οι κορουτίνες και πώς μπορείτε να χρησιμοποιήσετε τις πιο προηγμένες λειτουργίες τους, ανατρέξτε στο επίσημη τεκμηρίωση Kotlin.