40

This is my code:

In onCreate:

 new LoadMusicInBackground().execute();

Then towards the end of my main class I have this code

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

If the music has not loaded I am getting a nullpointer exception, looking at the docs I see there is a getStatus() but I have tried something like this:

music_load_status=LoadMusicInBackground.getStatus()

and that is not working :( How do I check if the background task is complete and the music has loaded?

Thanks!
Ryan

Ryan
  • 9,821
  • 22
  • 66
  • 101

3 Answers3

171

getStatus() checks whether the the AsyncTask is pending, running, or finished.

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
}

If you want to check if your action actually succeeded (i.e. the music was successfully loaded), then you need to come up with your own method that determines that. The getStatus() can only determine the state of the actual thread in AsyncTask.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • 13
    To clarify: FINISHED is the status AFTER onPostExecute was called. If you check the status durning onPostExecute the status will be RUNNING – user123321 Aug 24 '13 at 03:05
  • 1
    then why it return RUNNING in postexcute, its bit of surprising – Tofeeq Ahmad Oct 09 '13 at 05:41
  • 4
    it also worth mentioning that, if the task was cancelled by calling cancel() method on it, it still will be returning RUNNING status. – user2758776 May 15 '14 at 17:56
  • @user2758776 It should be returning RUNNING as long as "onPostExecute" has not been called yet. Calling cancel doesn't actually stop a thread. It just tells the thread that a cancel has been called on it. – DeeV May 15 '14 at 18:34
  • @DeeV exactly. just wanted to clarify that, because it's not very obvious – user2758776 May 19 '14 at 17:41
  • According to the docs onPostExecute is not called when the task is cancelled. But instead onCancelled is called in UI thread. But will the status be AsyncTask.Status.FINISHED then? Because the doc says that this status is only set when onPostExecute was called. – Matthias Jun 27 '14 at 08:43
  • 1
    @Matthias: Good catch. Looking at the source code it looks like this was the case before Honeycomb. Now, instead of onPostExecute(Object Result) you get onCancelled(Object result) called instead, but now FINISHED should be set. Looks like you always need to check "isCanceled()" to be on the safe side. – DeeV Jun 27 '14 at 16:45
  • Good point - to check if the task was cancelled even if you are in onPostExecute – Matthias Jun 27 '14 at 17:03
18

This is asynchronous programing - you should not check from UI thread, because this means that you are blocking the UI thread ( presumably running check in loop with Thread.sleep()?).

Instead you should be called when AsyncTask is done: from it's onPostExecute() call whatever method in Activity you need.

Caveat: the downside of this approach is that Activity must be active when background thread finishes. This is often not the case, for example if back is prwssed or orientation is changed. Better approach is to send a broadcast from onPostExecute() and then interested activities can register to receive it. Best part is that Activity only receives broadcast if it's active at that time, meaning that multiple Activities can register, but only the active one will receive it.

Peter Knego
  • 79,991
  • 11
  • 123
  • 154
9

Create asynctask with listener

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

And use the Asynctask

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

I hope this might help some people

Rumid
  • 1,627
  • 2
  • 21
  • 39
Aristo Michael
  • 2,166
  • 3
  • 35
  • 43