1

ゲームを実装していますが、UI とは別のスレッドで実行される MediaPlayer インスタンスを 1 つだけ使用したいと考えています。各オーディオ ファイルは FIFO キューに送信され、ファイルが再生されていない場合はすぐに再生されるか、キュー内の前のファイルが終了するとすぐに再生されます。これをサポートするシングルトン クラスを次のように実装しました。

public class ThePlayer {
private static ThePlayer instance = null;
private Context context;
Thread playerThread;
BlockingQueue<Integer> listIDs = new LinkedBlockingQueue<Integer>();
MediaPlayer player;
Integer playID; 

private ThePlayer() {
    player = null;
    playerThread = new Thread(new Runnable() {
        //Object locker = new Object();
        public void run() {
            while (true) {
                try {
                    playID = listIDs.take(); // blocks if list empty
                    Log.d(this.getClass().getName(), "Took ID 0x" + Integer.toHexString(playID));
                    player = MediaPlayer.create(context, playID); 
                    player.setOnCompletionListener(
                            new MediaPlayer.OnCompletionListener() {
                                public void onCompletion(MediaPlayer mp) {
                                        mp.release();
                                        mp = null;
                                        synchronized (playerThread) {
                                            Log.d(this.getClass().getName(), "Finished playing 0x"+Integer.toHexString(playID));
                                            playerThread.interrupt();
                                        }
                                }
                            });
                    player.start();
                    Log.d(this.getClass().getName(), "Started playing 0x"+Integer.toHexString(playID));
                    synchronized (this) {
                        Log.d(this.getClass().getName(), "Now wait to finish");
                        wait(); // until finished playing
                    }                       
                } catch (InterruptedException ie) {
                    Log.d(getClass().getName(), "Player thread wait interrupted");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    });
    playerThread.setName("PlayerThread");
    playerThread.start();
}


public static ThePlayer getInstance()
{
    if(instance == null)
    {
        instance = new ThePlayer();
    }
    return instance;
}

public void play(Context _ctx, int id) {
    context = _ctx;
    listIDs.add(id);
    Log.d(this.getClass().getName(), "Added ID 0x" + Integer.toHexString(id));
}

public void stop() {
    //TODO: implement
}

}

一般に、これはうまく機能しますが、ある特定のファイルが一貫性のない方法で再生できません。つまり、ほとんどの場合は再生されませんが、再生されることがあります。すべてのログ エントリは、ファイルがキューに入れられたこと、MediaPlayer が割り当てられて開始されたこと、および onCompletion 関数が呼び出されたことを示しています。例外がスローされることはありません。これは、Motorola Defy+ 電話とさまざまなエミュレータ構成で発生します。これは、私の Samsung Galaxy Tab II 10.1 では発生しません。これは、より高性能なハードウェア、または Android のより高度なバージョンの機能であると推測されます。

4

0 に答える 0