Android AsyncTask -käyttäytyminen muuttuu, minkä sinun pitäisi tietää

Google haluaa sinun rakastavan sen Android AsyncTask -mallia. Myönnän, että tullessani sulautetusta C / C ++ -taustasta olin hieman skeptinen suhtautuvani pitkäaikaisen I / O-siirron siirtämiseen mustaan ​​laatikkoon tarkoitettuun säiealtaan. Ajan myötä kuitenkin arvostin luokkaa ja sen yksinkertaisuutta. Se toimi hyvin, ja minun ei tarvinnut huijata sitä.

Viime viikolla törmäsin kuitenkin odottamattomaan käyttäytymiseen. Käyttäjä ilmoitti erittäin hitaasta I / O-toiminnasta yhdessä sovelluksessani, kun hän oli päivittänyt vanhemmasta laitteesta uuteen. Tämä oli päinvastainen kuin mitä voidaan odottaa, joten heitin nopeasti yhteen alkeellisen testin vetääksesi joitain mittareita.

Harkitse seuraavaa koodinpätkä:

 varten ( int i = 0; i <5; i ++) { 
 AsyncTask1 tehtävä = uusi AsyncTask1 (); 
 task.execute (); 
 } 

Edes tietämättä, mitä AysncTask1-toteutuksessa tapahtuu, mielestäni tarkoituksena on käynnistää viisi näistä tehtävistä. Joten testin tarkoituksia varten simuloin pitkää käynnissä olevaa I / O: ta ohittamalla AsyncTask1: n doInBackground-toiminnon nukkumaan 1000 millisekunnin ajan.

 @Ohittaa 
 suojattu objekti doInBackground (Object ... arg0) kokeile { 
 Lanka. nukkua ( ONE_SECOND ); 
 } saalis (InterruptedException e) {// TODO Automaattisesti luotu saalislohko 
 e.printStackTrace (); 
 } 
 palauta nolla ; 
 } 
Laadittuani joitain perusvirheen ajastimia, suoritin koodin kahdelle AVD-ilmentymälle: toisessa käynnissä Eclair (Android 2.0) ja toisessa Jelly Bean (Android 4.2). Tulokset yllättivät minut. Katso itseäsi ( kuva A ). Kuvio A

Se on totta - Android 2.0 jätti viimeisimmän ja suurimman version käyttöjärjestelmän pölystä. Sinun ei tarvitse olla niin ahkera kertoaksesi sekunnin viiveemme, jonka koodattiin AsyncTask-sovellukseemme, viidellä it-loop-iteraatiolla arvataksesi mitä tapahtuu: Android suorittaa tehtäviä sarjasi eikä samanaikaisesti. Aloin pilata foorumeilla ja lopulta ohjattiin takaisin Googlen AsyncTaskin dokumentaatioon. Noin kolmanneksella sivusta alaspäin löydät seuraavan huomautuksen:

"Alkaen HONEYCOMB: lla, tehtävät suoritetaan yhdellä säikeellä, jotta vältetään rinnakkaisen suorituksen aiheuttamat yleiset sovellusvirheet.

Jos haluat todella samanaikaisen suorittamisen, voit vedota executeOnExecutor (java.util.concurrent.Executor, Object ) kanssa THREAD_POOL_EXECUTOR. "

Minun näkökulmastani tämä on vähän vastaintuitiivista. Lisäksi haluaisin, että tämän suuruusluokan käyttäytymismuutoksista ilmoitetaan soittamalla pasuunoilla ja kuullessasi! Kuule! Siitä huolimatta Eclairissa havaitun käyttäytymisen säilyttäminen on yksinkertainen ratkaisu.

 int currentapiVersion = android.os.Build.VERSION. SDK_INT ; 
 varten ( int i = 0; i <5; i ++) { 
 AsyncTask-tehtävä = uusi AsyncTask1 (); 
 if (currentapiVersion> = 
 android.os.Build.VERSION_CODES. HONEYCOMB ) {tehtävä.executeOnExecutor (AsyncTask. THREAD_POOL_EXECUTOR ); 
 } muuta { 
 task.execute (); 
 } 
 } 
Kuten alla olevasta taulukosta voidaan nähdä, suoritusnopeus palautettiin ( kuva B ). Kuvio B

Erityisesti sovellukselleni vaikutus ei ollut valtava, jos käyttäytymisen muutos on ollut olemassa Honeycomb-julkaisun jälkeen ja olen juuri kuullut siitä. Haluan silti, kuten useimmat kehittäjät, tarjota käyttäjille optimaalisen kokemuksen. Oletin (väärin), että uudempi käyttöjärjestelmä tarkoitti, että asiat toimisivat ainakin samalla nopeudella, ellei jopa nopeammin. Läksy opittu.

Jos et ole katsonut AsyncTask-asiakirjoja jonkin aikaa, suosittelen, että valitset itsesi uudelleen heidän kanssaan. Koodissani on epätodennäköistä, että suoritan asynkronisia tehtäviä tulevaisuudessa käyttämättä onExecutor-menetelmää.

© Copyright 2020 | mobilegn.com