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() メソッドによって返される 1 つのストリーム ID のみに設定します

この解決策はあまりきれいではありません...


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 に答える