为什么Android Async任务无法正常工作

时间:2013-07-11 06:40:35

标签: android android-asynctask

我有一个活动,这是splash activity,我想在其中加载2个音乐,当加载完成后我想开始我的欢迎页面,不幸的是我做错了。

即使我在加载完成时获得了log,但是当没有加载2首音乐时我也得到了日志..

日志

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

4 个答案:

答案 0 :(得分:2)

问题在于您是在每个Asynctask内创建一个单独的线程。当你打电话

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

一个单独的线程开始加载音乐。但是,AsyncTask将在其线程中继续,完成doInBackground,转到onPostexecute,当它到达那里时,将不会设置任何标志,因为soundPool1.load()和soundPool2.load ()`仍在运行

您的代码执行完全符合预期!

要解决此问题,使用您的代码结构,您需要向两个 doInBackground方法添加一些代码。这是更新的第2号:

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

然后它只会在音乐实际加载时到达onPostExecute。确保初始化标志也是明智之举,因此在每个AsyncTask:

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

如果您计划了很多AsyncTasks,请阅读thisthis

答案 1 :(得分:1)

从onCreate()中删除以下代码并将其加载到load1的PostExecute()

new Load2().execute(2);

并在load2的PostExecute()中编写启动欢迎活动。

答案 2 :(得分:0)

这里的逻辑错了。你已经开始了2个模拟工作。在每个工作中,你都要求加载两个雕像。

if (isLoad1 && isLoad2) {

}else{

}

我的解决方案是你可以创建第3个帖子。检查两者的加载状态。如果还没有准备好,那么再次睡觉并重新检查。希望这个帮助

答案 3 :(得分:0)

在我看来,异步任务很可能都正常运行,但是由于你无法预测它们完成的顺序,你无法预测这两个标志都会在postexecute中设置,实际上它很可能是不会。这将导致异步任务无法启动您的意图。此外,您可能希望将volatile修饰符添加到布尔标志,以确保始终使用“最新”值。实际上看着你的代码,我认为你真的不想使用两个异步任务......