ისევ იყენებთ AsyncTask-ს თქვენს Android აპებში? ალბათ აღარ უნდა იყო. აი, როგორ შევცვალოთ ისინი კოტლინის კორუტინებით.
Android-ში დიდი ხნის განმავლობაში, თუ აპის შექმნისას რაიმეს ასინქრონულად გაკეთება დაგჭირდათ, ალბათ იყენებდით AsyncTask-ს. AsyncTask არის API Android-ის ჩარჩოში, რომელიც აადვილებს (ish) ოპერაციების გაშვებას ფონზე და მნიშვნელობების დაბრუნებას დასრულების შემდეგ. და ამას აზრი აქვს. Kotlin's Coroutines-ისგან განსხვავებით, AsyncTask უკვე დიდი ხანია არსებობს და ის ზუსტად არის ჩაშენებული.
თუმცა, როგორც დიზაინის ფილოსოფია, ასევე AsyncTask-ის განხორციელება წლების განმავლობაში გარკვეულწილად მოძველდა. ამის გამო Google-ს აქვს მოძველდა AsyncTask API. თქვენ კვლავ შეგიძლიათ გამოიყენოთ ის, თუ გსურთ, მაგრამ Google არ გირჩევთ ამის გაკეთებას. საბედნიეროდ, არსებობს AsyncTask-ის ალტერნატივების მთელი თაიგული, მათ შორის კოტლინის ენის მახასიათებელი - კორუტინი.
Kotlin's coroutines API წარმოუდგენლად ძლიერი ჩარჩოა, რომელიც საშუალებას გაძლევთ გააკეთოთ მთელი რიგი რამ. ეს სტატია აპირებს მხოლოდ იმის გარკვევას, რაც შესაძლებელია. ჩვენ განვიხილავთ საფუძვლებს, რომლებიც საჭიროა AsyncTask-დან კორუტინებზე გადასასვლელად.
კორუტინის მხარდაჭერის დამატება
სანამ დაიწყებთ კორუტინის გამოყენებას, თქვენ რეალურად უნდა დაამატოთ ისინი თქვენს პროექტში.
კოტლინის მხარდაჭერის დამატება
თუ უკვე გაქვთ კოტლინი დანერგილი, გადადით შემდეგ განყოფილებაზე. წინააღმდეგ შემთხვევაში, თქვენ უნდა დაამატოთ Kotlin მხარდაჭერა თქვენს პროექტში. შეამოწმეთ ჩემი სახელმძღვანელო კოტლინის არსებულ პროექტში დამატების შესახებ დამატებითი დეტალებისთვის.
კორუტინის ბიბლიოთეკების დამატება
თქვენს მოდულის დონეზე build.gradle
, მოიცავს შემდეგ დამოკიდებულებებს.
dependencies {
...
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-core: 1.5.0'
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-android: 1.5.0'
}
დაასინქრონეთ თქვენი პროექტი და კოტლინის კორუტინები ახლა ხელმისაწვდომი იქნება გამოსაყენებლად.
კორუტინის გამოყენება
CoroutineScope-ის დანერგვა
კორუტინის გამოსაყენებლად, თქვენ უნდა გქონდეთ ხელმისაწვდომი CoroutineScope ეგზემპლარი. ამის გაკეთების მარტივი გზაა მისი დანერგვა თქვენს შემცველ კლასში.
მაგალითად, CoroutineScope-ის განსახორციელებლად აქტივობაში:
classSomeActivity : AppCompatActivity, CoroutineScope by MainScope() {
...
override fun onDestroy(){
super.onDestroy()
cancel()
}
}
ეს აიძულებს SomeActivity განახორციელოს CoroutineScope ინტერფეისი MainScope კლასის მეშვეობით. MainScope გაუმკლავდება CoroutineScope-ის განხორციელების ყველა ლოგიკას, ხოლო საშუალებას მოგცემთ გამოიყენოთ CoroutineScope მეთოდები. რეკავს cancel()
in onDestroy()
დარწმუნდება, რომ აქტივობის გასვლის შემდეგ ასინქრონული ლოგიკა არ გაგრძელდება.
AsyncTask-ის ჩანაცვლება Coroutines-ით
თქვით, რომ გაქვთ 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()
თუ გინდა. ასე რომ, ორიგინალური მაგალითი შეიძლება გახდეს მსგავსი რამ.
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
}
}
კონტექსტის გამოყენებით
მოხერხებულობისთვის 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 მარტივი კორუტინით.
დამატებითი ინფორმაციისთვის, თუ როგორ მუშაობს კორუტინი და როგორ შეგიძლიათ გამოიყენოთ მათი უფრო მოწინავე ფუნქციები, იხილეთ კოტლინის ოფიციალური დოკუმენტაცია.