2011-09-28 20 views
35

Questo è il mio codice:Android, AsyncTask, controlla lo stato?

In onCreate:

new LoadMusicInBackground().execute(); 

Poi, verso la fine della mia classe principale che ho questo codice

/** Helper class to load all the music in the background. */ 
class LoadMusicInBackground extends AsyncTask<Void, String, Void> { 
    @Override 
    protected Void doInBackground(Void... unused) { 

     soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 100); 
     soundPoolMap = new HashMap<Integer, Integer>(); 

     soundPoolMap.put(A1, 
       soundPool.load(GameScreen_bugfix.this, R.raw.a, 1)); 
     soundPoolMap.put(A3, 
       soundPool.load(GameScreen_bugfix.this, R.raw.b, 1)); 
     soundPoolMap.put(A5, 
       soundPool.load(GameScreen_bugfix.this, R.raw.c_s, 1)); 
     soundPoolMap.put(A6, 
       soundPool.load(GameScreen_bugfix.this, R.raw.d, 1)); 
     soundPoolMap.put(A8, 
       soundPool.load(GameScreen_bugfix.this, R.raw.e, 1)); 
     soundPoolMap.put(A10, 
       soundPool.load(GameScreen_bugfix.this, R.raw.f_s, 1)); 
     soundPoolMap.put(A12, 
       soundPool.load(GameScreen_bugfix.this, R.raw.g_s, 1)); 
     soundPoolMap.put(wrong, 
       soundPool.load(GameScreen_bugfix.this, R.raw.wrong2, 1)); 

     publishProgress(""); 
     Log.v("SOUNDPOOL", "" + soundPoolMap); 
     return (null); 
    } 

    @Override 
    protected void onProgressUpdate(String... item) { 
     // text1.setText(item[0]); 
    } 

    @Override 
    protected void onPostExecute(Void unused) { 
     //Toast.makeText(GameScreen_bugfix.this, "music loaded!", Toast.LENGTH_SHORT).show(); 
    } 
} 

Se la musica non ha caricato sto ottenendo un eccezione nullpointer, guardando la documentazione vedo c'è un getStatus(), ma ho provato qualcosa di simile:

music_load_status=LoadMusicInBackground.getStatus() 

e che non funziona :( Come posso controllare se l'attività in background è completa e la musica è stata caricata?

Grazie!
Ryan

risposta

156

getStatus() verifica se la la AsyncTask è in sospeso, in esecuzione, o finito.

LoadMusicInBackground lmib = new LoadMusicInBackground(); 

if(lmib.getStatus() == AsyncTask.Status.PENDING){ 
    // My AsyncTask has not started yet 
} 

if(lmib.getStatus() == AsyncTask.Status.RUNNING){ 
    // My AsyncTask is currently doing work in doInBackground() 
} 

if(lmib.getStatus() == AsyncTask.Status.FINISHED){ 
    // My AsyncTask is done and onPostExecute was called 
} 

Se si vuole verificare se la vostra azione in realtà è riuscito (vale a dire la musica era successo carico), allora avete bisogno di venire con il proprio metodo che determina che. Il getStatus() può solo determinare lo stato del thread attuale in AsyncTask.

+0

Grazie! Verificherò! – Ryan

+11

Per chiarire: FINISHED è lo stato che è stato chiamato AFTER onPostExecute. Se si verifica lo stato di durning onPostExecute lo stato sarà RUNNING – user123321

+0

quindi perché restituisce RUNNING in postexcute, il suo bit di sorprendente – Sameer

17

Questa è la programmazione asincrona - non si dovrebbe verificare dal thread dell'interfaccia utente, perché questo significa che si sta bloccando il thread UI (presumibilmente in esecuzione di controllo in loop con Thread.sleep()?).

Invece dovresti essere chiamato quando AsyncTask ha finito: dal suo onPostExecute() chiama qualsiasi metodo in Attività di cui hai bisogno.

Avvertenza: lo svantaggio di questo approccio è che l'attività deve essere attiva quando termina il thread in background. Questo spesso non è il caso, ad esempio se il ritorno è stato eseguito o l'orientamento è cambiato. Un approccio migliore è quello di inviare una trasmissione da onPostExecute() e quindi le attività interessate possono registrarsi per riceverlo. La parte migliore è che l'attività riceve broadcast solo se è attiva in quel momento, il che significa che più attività possono registrarsi, ma solo quella attiva la riceverà.

2

Creare AsyncTask con ascoltatore

class ClearSpTask extends AsyncTask<Void, Void, Void> { 

    public interface AsynResponse { 
     void processFinish(Boolean output); 
    } 

    AsynResponse asynResponse = null; 

    public ClearSpTask(AsynResponse asynResponse) { 
     this.asynResponse = asynResponse; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     showProgressDialog(); 
    } 

    @Override 
    protected Void doInBackground(Void... voids) { 
     cleardata(); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     hideProgressDialog(); 
     asynResponse.processFinish(true); 
    } 
} 

e utilizzare l'AsyncTask

new ClearSpTask(new ClearSpTask.AsynResponse() { 
     @Override 
     public void processFinish(Boolean output) { 
      // you can go here 
     } 
}).execute(); 

Spero che questo potrebbe aiutare alcune persone

Problemi correlati