Kaip vykdyti kodą paraleliniame (ne pagrindiniame) sraute?
sobes.tech AI
Atsakymas iš AI
Android naudoja įvairius mechanizmus, leidžiančius vykdyti kodą lygiagrečiai, nesukeliant pagrindinio (UI) srauto blokavimo ir išlaikant programėlės reakciją.
Android standartinės priemonės:
-
Thread: Pagrindinė naujo srauto kūrimo klasė.new Thread(new Runnable() { @Override public void run() { // Kodas, vykdomas lygiagrečiame sraute } }).start();Trūkumas: Rankinis srautų valdymas gali sukelti gyvenimo ciklo problemų ir atminties nutekėjimą.
-
AsyncTask(pasenusi): Supaprastino darbą su lygiagrečiais srautais ir sąveiką su UI srautu.private static class MyAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { // Kodas, vykdomas fono sraute return null; } @Override protected void onPostExecute(Void result) { // Darbas su UI srautu po doInBackground pabaigos } } // Naudojimas: new MyAsyncTask().execute();Trūkumai: Pasenusi, turi apribojimų ir sudėtingumų gyvenimo ciklo valdyme.
-
HandlerirLooper: Leidžia kurti srautus su žinučių apdorojimo ciklais.HandlerThread handlerThread = new HandlerThread("MyWorkerThread"); handlerThread.start(); Handler handler = new Handler(handlerThread.getLooper()); handler.post(new Runnable() { @Override public void run() { // Kodas, vykdomas su Looper sraute } });Privalumas: Patogu vykdyti pasikartojančias užduotis arba apdoroti asinchroninius įvykius atskirame sraute.
-
ExecutorService/ThreadPoolExecutor: Teikia srauto baseinus, kurie yra efektyvesni nei kurti naująThreadkiekvienai užduočiai.ExecutorService executor = Executors.newSingleThreadExecutor(); // Arba newCachedThreadPool(), newFixedThreadPool(N) executor.execute(new Runnable() { @Override public void run() { // Kodas, vykdomas iš srauto iš baseino } }); // Nepamiršti išjungti executor.shutdown() kai baigsitePranašumai: Valdo srautų kūrimą ir pakartotinį naudojimą, mažina išlaidas.
Šiuolaikiniai metodai:
-
Kotlin Coroutines: Lengvi srautai, siūlantys paprastesnį ir skaitomesnį būdą asinchroniniam programavimui.import kotlinx.coroutines.* // Korutinos paleidimas srauto baseine (analogas foniniam srautui) GlobalScope.launch(Dispatchers.Default) { // Kodas, vykdomas foniniame sraute } // Korutinos paleidimas darbui su IO operacijomis GlobalScope.launch(Dispatchers.IO) { // Kodas, vykdomas su IO operacijomis (tinklas, failai ir kt.) } // Perjungimas į UI srautą atnaujinti naudotojo sąsają GlobalScope.launch(Dispatchers.Default) { // Fono skaičiavimai withContext(Dispatchers.Main) { // UI atnaujinimas } }Pranašumai: Pagerinta kodo skaitomumas, efektyvesnis išteklių naudojimas, paprastas užduočių atšaukimas, struktūruotas konkurencingumas.
-
RxJava / RxKotlin: Reaktyvus programavimas, pagrįstas stebimais duomenų srautais.import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.schedulers.Schedulers; Observable.just("Tam tikras rezultatas") .subscribeOn(Schedulers.io()) // Vykdyti IO sraute .observeOn(AndroidSchedulers.mainThread()) // Stebėti UI sraute .subscribe(/* Rezultato apdorojimas */);Pranašumai: Galingas įrankis asinchroniniams įvykiams ir duomenų transformacijai, bet turi aukštesnį įsisavinimo barjerą.
WorkManager biblioteka:
WorkManager: Rekomenduojamas Architecture Components komponentas garantuotam foninių užduočių vykdymui, net jei programa uždaryta arba įrenginys perkrautas.Pranašumai: Garantija, kad užduotis bus įvykdyta, palaiko apribojimus (tinklo tipas, akumuliatoriaus įkrova), valdymas atšaukimui, atidėtas vykdymas ir pakartojimai.import androidx.work.* import java.util.concurrent.TimeUnit class MyWorker: Worker(appContext, workerParams) { override fun doWork(): Result { // Kodas, vykdomas foninėje užduotyje return Result.success() // Ar Result.failure(), Result.retry() } } // Užklausos sukūrimas užduočiai vykdyti val workRequest = OneTimeWorkRequestBuilder<MyWorker>() .setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()) // Pasirinktiniai apribojimai .build() // Užduoties iškėlimas į eilę WorkManager.getInstance(context).enqueue(workRequest)
Konkretaus metodo pasirinkimas priklauso nuo užduoties tipo, jos gyvenimo ciklo ir patikimumo reikalavimų. Dauguma šiuolaikinių Android programėlių rekomenduoja naudoti Kotlin Coroutines arba WorkManager.