Reputation: 10590
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..
Loaded 1 true
Loaded 2 true
1 not two
2 not two
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
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
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
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
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