ゲームを実装していますが、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 のより高度なバージョンの機能であると推測されます。