????????先说下思路,为了让任务一次执行,需要定义一个队列,以及一个正在执行的标志。 ????????任务来了之后,首先是判断当前队列是否为空,如果队列为空,或者正在执行,则加入队列中。否则直接执行处理。 ????????处理任务的过程中,需要将标记置为执行中,执行完成需要将标记置为执行完成,并且调用执行方法,传个空值。接收到空值之后,则去取队列下个任务,并且执行;如果队列为空,则停止执行,并将正在执行标志置为false。
class SpeakQueue {
// 是否正在播放
private var speaking: Boolean = false
// 创建队列
private var mesQueue: Queue<String>? = null
/**
* 监听RabbitMQ
*/
fun listenQueue(context: Context) {
mesQueue = LinkedBlockingQueue<String>(10000)
RabbitMQUtil.getInstance().receiveQueueMessage("00", object : RabbitMQUtil.ReceiveMessageListener {
override fun receiveMessage(message: String?) {
Log.d("消息:", message)
// 这里开始进行队列插入或者执行操作
speakMessage(message.toString(), context)
}
})
}
/**
* 判断加入队列还是直接执行
*/
fun speakMessage(callMessage: String, context: Context) {
if (speaking || !mesQueue!!.isEmpty()) {
// 正在执行操作或者队列不为空,则插入队列
mesQueue!!.offer(callMessage)
} else {
// 已经结束操作,则开始下一个操作
speak(callMessage, context)
}
}
/**
* 主逻辑代码
*/
fun speak(refText: String, context: Context) {
if (!TextUtils.isEmpty(refText)) {
speaking = true
object : Thread() {
override fun run() {
super.run()
try {
//休眠3秒
sleep(1000)
} catch (e: InterruptedException) {
e.printStackTrace()
}
/**
* 要执行的操作
*/
runOnUiThread {
Log.d("消息222:", refText)
showToast(context, "我就是一条消息")
speaking = false
object : Thread() {
override fun run() {
super.run()
try {
sleep(1000) //休眠3秒
} catch (e: InterruptedException) {
e.printStackTrace()
}
/**
* 要执行的操作
*/
runOnUiThread {
Log.d("消息333:", refText)
//当前播放完毕,则给个空,从消息队列取消息执行
speak("", context)
}
}
}.start()
}
}
}.start()
} else {
val callMessage: String? = mesQueue!!.poll()
if (callMessage != null) {
//获取消息,并且执行
speak(callMessage, context)
} else {
//消息为空,则认为执行完了
speaking = false
}
}
}
}
|