感谢@Mark W的答案。但我正在考虑不涉及明确延迟/睡眠的解决方案。
所以我正在实现这个服务类。
public class OrderNoticeService extends Service implements TextToSpeech.OnInitListener {
private List orderSpeechAsyncTasks = new ArrayList<>();
private TextToSpeech textToSpeech;
private Context context;
public void addToOrderNoticeQueue(int orderId) {
String orderSpeechText = String.format(getResources().getString(R.string.order_voice_over_default_text), Integer.toString(orderId));
orderSpeechAsyncTasks.add(new OrderSpeechAsyncTask(getApplicationContext(), R.raw.orderalert, orderSpeechText, textToSpeech, new AsyncTaskCallback() {
@Override
public void onTaskCompleted(Object response) {
}
}));
if (orderSpeechAsyncTasks.size() > 1) {
final OrderSpeechAsyncTask orderSpeechAsyncTask = orderSpeechAsyncTasks.get(orderSpeechAsyncTasks.size() - 1);
OrderSpeechAsyncTask orderSpeechAsyncTaskPrior = orderSpeechAsyncTasks.get(orderSpeechAsyncTasks.size() - 2);
orderSpeechAsyncTaskPrior.setAsyncTaskCallback(new AsyncTaskCallback() {
@Override
public void onTaskCompleted(Object response) {
try {
orderSpeechAsyncTask.execute();
System.out.println("Execution!");
} catch (Exception e) {
}
}
});
}
}
@Override
public void onCreate() {
textToSpeech = new TextToSpeech(this, this);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
return Service.START_STICKY;
}
private static final String TAG = "OrderNoticeService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "OrderNoticeService onBind");
return mBinder;
}
@Override
public void onDestroy() {
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
}
Log.i(TAG, "OrderNoticeService onDestroy");
}
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
OrderNoticeVoiceOverThread orderNoticeVoiceOverThread = new OrderNoticeVoiceOverThread(context, orderSpeechAsyncTasks);
orderNoticeVoiceOverThread.start();
} else {
System.out.println("Text To Speech not supported!");
}
}
private class OrderNoticeVoiceOverThread extends Thread {
private Context context;
private List orderSpeechAsyncTasks;
private boolean anyTaskRunning = false;
public OrderNoticeVoiceOverThread(Context context, List orderSpeechAsyncTasks) {
this.context = context;
this.orderSpeechAsyncTasks = orderSpeechAsyncTasks;
}
public void run() {
while (true) {
for (OrderSpeechAsyncTask orderSpeechAsyncTask : new ArrayList(orderSpeechAsyncTasks)) {
if (orderSpeechAsyncTask != null && orderSpeechAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING)) {
anyTaskRunning = true;
break;
}
}
if (!anyTaskRunning) {
for (OrderSpeechAsyncTask orderSpeechAsyncTask : new ArrayList(orderSpeechAsyncTasks)) {
if (orderSpeechAsyncTask != null && orderSpeechAsyncTask.getStatus().equals(AsyncTask.Status.PENDING)) {
orderSpeechAsyncTask.execute();
anyTaskRunning = false;
break;
}
}
}
}
}
}
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public OrderNoticeService getService() {
return OrderNoticeService.this;
}
}
}
而OrderSpeechAsyncTask如下。
public class OrderSpeechAsyncTask extends AsyncTask {
private static final String LOG_TAG = OrderSpeechAsyncTask.class.getSimpleName();
private MediaPlayer mediaPlayer;
private int soundId;
private Context context;
private String orderSpeechText;
private AsyncTaskCallback asyncTaskCallback;
private TextToSpeech textToSpeech;
public OrderSpeechAsyncTask(final Context context, int soundId, String orderSpeechText, TextToSpeech textToSpeech, AsyncTaskCallback asyncTaskCallback) {
this.context = context;
this.soundId = soundId;
this.orderSpeechText = orderSpeechText;
this.textToSpeech = textToSpeech;
this.asyncTaskCallback = asyncTaskCallback;
}
public AsyncTaskCallback getAsyncTaskCallback() {
return asyncTaskCallback;
}
public void setAsyncTaskCallback(AsyncTaskCallback asyncTaskCallback) {
this.asyncTaskCallback = asyncTaskCallback;
}
@Override
protected Void doInBackground(Void... params) {
mediaPlayer = MediaPlayer.create(context, soundId);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.release();
textToSpeech.speak(orderSpeechText, TextToSpeech.QUEUE_ADD, null, "ORDER_NO_" + orderSpeechText);
textToSpeech.playSilentUtterance(2000, TextToSpeech.QUEUE_ADD, "PAUSE_NO_" + orderSpeechText);
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
}
@Override
public void onDone(String utteranceId) {
asyncTaskCallback.onTaskCompleted(null);
}
@Override
public void onError(String utteranceId) {
}
});
}
});
mediaPlayer.start();
return null;
}
}
到目前为止,处理以下内容;
播放列表中的声音和文本
在仍在读取现有列表的同时将项添加到队列中
去做;
一旦完成现有项目的读取,这不会处理添加到列表中的任何新项目。