2011-09-28 14 views
35

To jest mój kod:Android, AsyncTask, sprawdź status?

W onCreate:

new LoadMusicInBackground().execute(); 

Następnie pod koniec mojego głównego klasy Mam ten kod

/** 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(); 
    } 
} 

Jeśli muzyka nie załadował Otrzymuję wyjątek nullpointer, patrząc na dokumenty, które widzę jest getStatus(), ale próbowałem coś takiego:

music_load_status=LoadMusicInBackground.getStatus() 

i to nie działa :( Jak sprawdzić, czy zadanie w tle zostało zakończone i załadowano muzykę?

Dzięki!
Ryan

Odpowiedz

156

getStatus() sprawdza, czy jest w toku, działa, czy skończył.

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 
} 

Jeśli chcesz sprawdzić, czy działanie rzeczywiście udało (tzn muzyka była pomyślnie załadowany), to trzeba wymyślić własną metodę, która określa, że. Model getStatus() może określić tylko stan bieżącego wątku w AsyncTask.

+0

Dzięki! Sprawdzę to! – Ryan

+11

Aby wyjaśnić: ZAKOŃCZONO jest wywołany status PO ON onPostExecute. Jeśli sprawdzisz status w momenciePostExecute, status będzie RUNNING – user123321

+0

, to dlaczego powraca RUNNING w postexcute, nieco zaskakujący – Sameer

17

To jest programowanie asynchroniczne - nie powinieneś sprawdzać z wątku UI, ponieważ oznacza to, że blokujesz wątek UI (prawdopodobnie uruchamiasz pętlę check with Thread.sleep()?).

Zamiast tego powinno zostać wywołane, gdy wykonywanie zadania AsyncTask jest zakończone: od jego wywołania należy wykonać dowolną metodę w czynności, której potrzebujesz.

Zastrzeżenie: wadą tego podejścia jest to, że aktywność musi być aktywna po zakończeniu wątku tła. Zdarza się to często, na przykład w przypadku zmiany orientacji lub zmiany orientacji. Lepszym rozwiązaniem jest wysłanie transmisji z onPostExecute(), a następnie zainteresowane działania mogą zarejestrować się, aby ją otrzymać. Najlepsze jest to, że Activity odbiera tylko transmisje, jeśli są aktywne w tym czasie, co oznacza, że ​​wiele działań może się zarejestrować, ale tylko aktywny otrzyma je.

2

Tworzenie asynctask ze słuchaczem

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); 
    } 
} 

i użyć Asynctask

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

Mam nadzieję, że to może pomóc niektórym ludziom

Powiązane problemy