Marco Dinatsoli
Marco Dinatsoli

Reputation: 10590

Why in Android Async task not working as it supposed to Do

I have an activity, this is the splash activity, I want to load 2 music in it and when the loading is finish I want to start my welcome page, unfortunately I made something wrong.

Even though I got the log which I made when the load is complete , but I also got the log when the 2 music are not loaded..

Log

Loaded 1 true
Loaded 2 true
1 not two
2 not two

code

package com.Syriatel.EatTel;

import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

public class Splash extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);
        new Load1().execute(1);
        new Load2().execute(2);
    }

    public int soundID, soundID2;

    private SoundPool soundPool1, soundPool2;
    boolean isLoad1, isLoad2;

    class Load2 extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);
            if (isLoad1 && isLoad2) {
                Intent intent = new Intent(Splash.this, Welcome.class);
                finish();
                startActivity(intent);
            }else{
                Log.e("2", "not two");
            }
        }

        @Override
        protected Integer doInBackground(Integer... params) {
            soundPool2 = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
            soundPool2.setOnLoadCompleteListener(new OnLoadCompleteListener() {
                @Override
                public void onLoadComplete(SoundPool soundPool, int sampleId,
                        int status) {
                    isLoad2 = true;
                    Log.e("Loaded 2", "true");
                }
            });
            soundID2 = soundPool2.load(getApplicationContext(), R.raw.select, 1);
            return 1;
        }

    }

    class Load1 extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);
            if (isLoad1 && isLoad2) {
                Intent intent = new Intent(Splash.this, Welcome.class);
                finish();
                startActivity(intent);
            }else{
                Log.e("1", "not two");
            }
        }

        @Override
        protected Integer doInBackground(Integer... params) {
            soundPool1 = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
            soundPool1.setOnLoadCompleteListener(new OnLoadCompleteListener() {
                @Override
                public void onLoadComplete(SoundPool soundPool, int sampleId,
                        int status) {
                    isLoad1 = true;
                    Log.e("Loaded 1", "true");
                }
            });
            soundID = soundPool1.load(getApplicationContext(), R.raw.thip, 1);
            return 1;
        }
    }
}

Upvotes: 0

Views: 727

Answers (4)

Neil Townsend
Neil Townsend

Reputation: 6084

The problem is that you are creating a separate thread from within each Asynctask. When you call

soundID = soundPool1.load(getApplicationContext(), R.raw.thip, 1);

a separate thread starts loading the music. However, the AsyncTask will continue in its thread, complete doInBackground, go to onPostexecute and when it gets there neither of the flags will be set because soundPool1.load() and soundPool2.load()` are still running.

Your code is executing exactly as one would expect!

To solve this, using your code structure, you need to add some code to both doInBackground methods. Here is number 2 updated:

protected Integer doInBackground(Integer... params) {
    soundPool2 = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
    soundPool2.setOnLoadCompleteListener(new OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
            isLoad2 = true;
            Log.e("Loaded 2", "true");
        }
    });
    soundID2 = soundPool2.load(getApplicationContext(), R.raw.select, 1);

    // New Code so we wait until the load is complete
    while(isLoad2 == false) {
        Thread.sleep(1000); // 1 second (change as you feel fit)
    }

Then it will only get to onPostExecute when the music has actually loaded. It would also be wise to make sure you initialise the flags, so in each AsyncTask:

@override
protected void onPreExecute() {
    isLoadX = false
}

If you are planning a lot of AsyncTasks, you should read this and this.

Upvotes: 2

C B J
C B J

Reputation: 1868

It looks to me like it is quite likely both async tasks are running correctly, but because you can't predict which order they finish you cant predict that both flags will be set in the postexecute, in fact it is quite likely they wont be. This will result in both async tasks failing to start your intent. Additionally you might want to add the volatile modifier to the boolean flags to ensure the "freshest" value is always used. Actually looking at your code, I don't think you really want to use two async tasks...

Upvotes: 0

dd619
dd619

Reputation: 6200

Remove following code from your onCreate() and put on PostExecute() of load1

new Load2().execute(2);

and write launch your welcome activity in PostExecute() of load2.

Upvotes: 1

Van Vu
Van Vu

Reputation: 303

Sth wrong about logic in here. You've started 2 simulate jobs. And in each jobs you ask for loaded statues of both.

if (isLoad1 && isLoad2) {

}else{

}

My solution is that you could create 3rd thread. Check for loaded statuses of both. If it's not ready then sleep and recheck again. Hope this help

Upvotes: 0

Related Questions