Android 小技巧—一个特别简单的队列功能

身为一名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)
    }
}

我代码都贴出来了,大家一看就知道 这个也太简单了。就不多解释了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值