0

我有一个活动,这是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

4 回答 4

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

于 2013-07-11T07:05:38.677 回答
1

从您的 onCreate() 中删除以下代码并放入 load1 的 PostExecute()

new Load2().execute(2);

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

于 2013-07-11T06:50:16.917 回答
0

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

if (isLoad1 && isLoad2) {

}else{

}

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

于 2013-07-11T06:50:14.887 回答
0

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

于 2013-07-11T06:55:36.603 回答