注册

一个特别简单的队列功能

背景


身为一名ui仔,不光要会画ui,也有可能接触一些其他的需求,就比如我做直播的时候,就需要做礼物的队列播放,用户送礼,然后客户收到消息,然后一次播放礼物动画,这个需求很简单,自定义一个view并且里面有一个队列就可以搞定,但是如果要播放不同类型的内容,如果再去改这个ui,耦合度就会越来越大,那么这个view的定义就变了,那就太不酷啦,所以要将队列和ui拆开,所以我们要实现一个队列功能,然后可以接受不同类型的参数,然后依次执行。


如何实现的


一、咱们有两个队列,一个更新ui,一个缓存消息


二、咱们还要定时器,要轮询的检查任务


三、我们还要有队列进入的入口


四、我们也需要有处理队列的地方


五、我们还要有最后处理结果的方案


六、还得需要一个清除的功能,要不怎么回收呢


举一个栗子🌰


假设我们有个需求,收到消息后,弹出一个横幅通知,弹出横幅通知后几秒后消失,但是在这几秒中,会收到多条消息,你需要将这多条消息合并展示,听起来是不是很耳熟,就是说咱们聊天消息,一条消息展示一条内容,多条消息做合并。
现在看实际代码:如下所示

/**
* 堆栈消息帮助类
* */
object QueuePushHelper {
/**
* 通过type修改监听状态
* */
private var type = false


private var queuePushInterface: QueuePushInterface? = null

fun setQueuePushInterface(queuePushInterface: QueuePushInterface) {
this.queuePushInterface = queuePushInterface
}

/**
* 缓存所有消息
*/
private var cacheGiftList: LinkedList<QueuePushBean> =
LinkedList<QueuePushBean>()

/**
* 用于更新界面消息的队列
*/
private var uiMsgList: LinkedList<QueuePushBean> =
LinkedList<QueuePushBean>()

/**
* 定时器
*/
private var msgTimer = Executors.newScheduledThreadPool(2)

private lateinit var futures: ScheduledFuture<*>

/**
* 消息加入队列
*/
@JvmStatic
@Synchronized
fun onMsgReceived(customMsg: QueuePushBean) {
cacheGiftList.offer(customMsg)
}

/**
* 清空队列
* */
fun clearQueue() {
if (cacheGiftList.size > 0) {
cacheGiftList.clear()
}
if (uiMsgList.size > 0) {
uiMsgList.clear()
}
updateStatus(true)
}

/**
* 修改队列状态
* */
fun updateStatus(status: Boolean) {
type = status
}

/**
* 开启定时任务,数据清空
* */
@JvmStatic
fun startReceiveMsg() {
if (cacheGiftList.size > 0) {
cacheGiftList.clear()
}
if (uiMsgList.size > 0) {
uiMsgList.clear()
}
updateStatus(true)
futures = msgTimer.scheduleAtFixedRate(
TimerTask(),
0,
500,
TimeUnit.MILLISECONDS
)
}

/**
* 结束定时任务,数据清空
* ### 退出登录,需要清楚
* */
fun stopReceiveMsg() {
updateStatus(false)
if (cacheGiftList.size > 0) {
cacheGiftList.clear()
}
if (uiMsgList.size > 0) {
uiMsgList.clear()
}
if (::futures.isInitialized) {
futures.cancel(true)
}
msgTimer.shutdown()
}

/**
* 定时任务
* */
class TimerTask : Runnable {
override fun run() {
try {
synchronized(cacheGiftList) {
if (type) {
if (cacheGiftList.isNullOrEmpty()) {
return
}
uiMsgList.clear()
uiMsgList.offer(cacheGiftList.pollLast())
uiMsgList.poll()?.let {
if (cacheGiftList.size > 1) {
it.type = true
}
//poll一个用户信息,且从剩余集合中过滤出第一个不同名字的用户
queuePushInterface?.handleMessage(
it,
cacheGiftList.firstOrNull { its->
it.msg.fromNick !=its.msg.fromNick
}?.msg?.fromNick,
cacheGiftList.size + 1 // 因为poll了一个 所以数量加1
)
}
cacheGiftList.clear()
}
}
} catch (e: Exception) {
Log.d("QueuePushHelper", "run: e $e")
}
}
}

interface QueuePushInterface {

fun handleMessage(item: QueuePushBean, name: String?, msgCount: Int)
}
}

我代码都贴出来了,大家一看就知道 这个也太简单了。就不多解释了,如果还需要解释就留言吧,祝大家事事平安


作者:每天都好困啊
链接:https://juejin.cn/post/7225198413163479096
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册