1

据我所知,我的应用程序运行良好,但我注意到 SoundPool 的这个错误经常在 logcat 中报告。

E/SoundPool(28182): 2 mChannels.erase can not get the lock

关于什么会导致这种情况的任何想法?我尝试删除我的线程同步代码,但我仍然收到错误。

这是使用运行 Android 2.3.6 的 Galaxy S2 (SC-02C) 观察到的。

4

2 回答 2

2

我为您提出的另一个解决方案:

  • 通过 maxStreams = 1 的声音创建 SoundPool 的实例
  • 将音量 0 设置为仅由 play() 方法返回的一个 streamID

我同意这个解决方案不是很干净......


public class Sound {

    public final static int STREAM = AudioManager.STREAM_SYSTEM;

    private SoundPool pool;
    private int soundID;
    private int streamID;

    public Sound(Context context, int resID) {
        pool = new SoundPool(1, STREAM, 0);
        soundID = pool.load(context, resID, 1);
    }

    public final void play() {
        streamID = pool.play(soundID, 1, 1, 1, 0, 1);
    }

    public final void stop() {
        pool.setVolume(streamID, 0, 0);
    }

}

public class MyActivity extends Activity {

    public static Sound alarm1;
    public static Sound alarm2;

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setContentView(R.layout.main);

        setVolumeControlStream(Sound.STREAM);
        if(alarm1 == null) alarm1 = new Sound(this, R.raw.alarm1);
        if(alarm2 == null) alarm2 = new Sound(this, R.raw.alarm2);

        findViewById(R.id.play_1).setOnClickListener( new OnClickListener() {
            @Override public void onClick(View view) { alarm1.play(); }
        });
        findViewById(R.id.stop_1).setOnClickListener( new OnClickListener() {
            @Override public void onClick(View view) { alarm1.stop(); }
        });
        findViewById(R.id.play_2).setOnClickListener( new OnClickListener() {
            @Override public void onClick(View view) { alarm2.play(); }
        });
        findViewById(R.id.stop_2).setOnClickListener( new OnClickListener() {
            @Override public void onClick(View view) { alarm2.stop(); }
        });
    }

}

为了管理你所有的声音,我们可以想象一个这样的库:


public class Soundlib {

    private Context context;
    private HashMap<Integer, Sound> library;

    public Soundlib(Context context) {
        this.context = context;
        library = new HashMap<Integer, Sound>();
    }

    public final void add(int... rawID) {
        for(int id : rawID) library.put(id, new Sound(context, id));
    }

    public final void play(int... rawID) {
        for(int id : rawID) library.get(id).play();
    }

    public final void stop(int... rawID) {
        for(int id : rawID) library.get(id).stop();
    }

    public final void stopAll() {
        for(int id : library.keySet()) stop(id);
    }

}

// to initilize sound library
if(soundlib == null) soundlib = new Soundlib(this){{
    // to add one or more sounds
    add(R.raw.alarm1, R.raw.alarm2);
}};

// to play one or more sounds
soundlib.play(R.raw.alarm1);

// to stop one or more sounds
soundlib.stop(R.raw.alarm1);

// to stop all sounds
soundlib.stopAll();

于 2012-06-12T13:10:54.063 回答
0

我认为这个错误日志是由SoundPool 实例的play() / stop()方法引起的。

您是否尝试播放/停止音频流?

于 2012-06-08T23:44:37.800 回答