美文网首页
Timer实现周期任务队列的调度

Timer实现周期任务队列的调度

作者: Spirituality韬 | 来源:发表于2018-12-03 14:03 被阅读0次

    Timer、TimerTask使用

    • 最近有个需求TV上CA卡的问题,底层调用Topreal那边过来的接口,取得结构体,然后取得结构体里面值传输到应用层来,应用层接受解析数据,通过值来显示在Android TV上

    其中就有Fingerprint、Announcement message是底层主动发送上来的(也有应用层发送到底层,底层返回数据),其中应用层显示。

    需求就是显示fingerprint持续时间+间隔时间为一个周期,规定显示次数,如果达到则从TaskQueue中取一个Task继续执行。

    Fingerprint是不断从底层发送来的,接受后就显示出来,如果当前正在显示fingerprint,那就压入队列中,等到当前fingerprint执行完成就从队列中取出来显示。

    其实将每次接受到底层数据作为一个任务,然后压入任务队列,实现好其中的逻辑处理就很好实现了。

    FingerPrintTask.java

    extends TimerTask
    
    public FingerPrintTask(String dEventString) {
        ...
        //数据参数解析,并且赋值于成员变量
    }
    
    @Override
    public void run() {
        if(fingerPrintDispType == 0) {
            Message msg = new Message();
            msg.what = TOPREAL_SHOW_OVERT_FINGERPRINT;
            IptvActivity.mainactivity.handler.sendMessage(msg);
        }else if (fingerPrintDispType == 1){
            Message msg = new Message();
            msg.what = TOPREAL_SHOW_COVERT_FINGERPRINT;
            IptvActivity.mainactivity.handler.sendMessage(msg);
        }
        repeatCount++;
        if(repeatCount > fingerPrintShowRepeat)
            this.cancel();
    }
    
    • 接受数据并且将其解析为FingerPrintTask,其中该类继承TimerTask,实现其中的run()方法,通过fingerPrintDispType的类型发送不同的消息处理。mCurFingePrintTask存在时,新接收到底层数据,则继续解析,放入TaskQueue中。

    TaskQueue.java

    public class TaskQueue<E>  {
    
        private class Node {
            private E data;
            private Node next;
    
            public Node() {
            }
    
            private Node(E data) {
                this.data = data;
            }
    
            public Node(E data, Node next) {
                this.data = data;
                this.next = next;
            }
        }
    
        private Node front;
        private Node rear;
        private int count;
    
    
        public TaskQueue() {
            Node p = new Node();
            p.data = null;
            p.next = null;
            front = rear = p;
        }
    
    
        public boolean isEmpty(){
            return rear==front;
        }
      
        public void enqueue(E task){
            if(!isEmpty()) {
                if (task instanceof FingerPrintTask ) {
                    FingerPrintTask temp = (FingerPrintTask) task;
                    Node p = this.front.next;
                    while (p != null) {
                        if (((FingerPrintTask) p.data).getdEventString().equals(temp.getdEventString())) {
                            return;
                        }
                        p = p.next;
                    }
                }
            }
            if(!isEmpty()) {
                if (task instanceof AnnounceTask ) {
                    AnnounceTask temp = (AnnounceTask) task;
                    Node p = this.front.next;
                    while (p != null) {
                        if (((AnnounceTask) p.data).getdEventString().equals(temp.getdEventString())) {
                            return;
                        }
                        p = p.next;
                    }
                }
            }
            Node newNode = new Node();
            newNode.data = task;
            newNode.next = null;
            this.rear.next = newNode;
            this.rear = newNode;
            count++;
        }
    
        public E dequeue() throws Exception {
            if (isEmpty()) {
                throw new Exception("FingerPrint Task Queue is Empty");
            } else {
                E task;
                Node p = this.front.next;
                task = p.data;
                this.front.next = p.next;
    
                if (rear == p) {
                    rear = front;
                }
                count--;
                return task;
            }
        }
    
        public int length(){
            return count;
        }
    
        public void clear(){
            int length = length();
            for (int i = 0; i < length; i++) {
                try {
                    dequeue();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        public E findNode(int index){
            Node node = this.front;
            for (int i = 0; i <= index ; i++) {
                node=node.next;
            }
            return node.data;
        }
    
        public void remove(int index) {
            Node p = this.front;
            for (int i = 0; i < index ; i++) {
                p = p.next;
            }
            if(index == count - 1)
                this.rear = p;
            p.next = p.next.next;
            count--;
        }
    }
    
    • MainActivity.java代码
    //receive DS message, enqueue TaskQueue.
    private void addToprealFPTaskQueue(String dEventString) {
        FingerPrintTask fingerPrintTask = new FingerPrintTask(dEventString);
        if(mCurFingerPrintTask != null){
            if(fingerPrintTask.getdEventString().equals(mCurFingerPrintTask.getdEventString())) {
                return;
            }
        }
        if(mCurFingerPrintTask == null) {
            mCurFingerPrintTask = fingerPrintTask;
            toprealFPTimer.schedule(mCurFingerPrintTask,0,
                    (mCurFingerPrintTask.getFingerPrintFadeDuration() + mCurFingerPrintTask.getFingerPrintShowDuration()) * 1000);
        }else{
            fingerPrintTaskQueue.enqueue(fingerPrintTask);
        }
    }
    

    接收到底层消息,

    1.判断当前Task是否正在执行,如果没有并且与正在传来的消息equals,则return

    2.如果不为空且不相等,则如队列

    3.如果为空,则作为当前Task并且立即执行,这里任务都调用timer.schedule(timertask,delay,duration)方法执行。

    • 上面代码中说明run方法中用Handler机制来处理
    case TOPREAL_SHOW_OVERT_FINGERPRINT:
        //需要执行的任务,这里是显示对话框
        ....
        handler.sendEmptyMessageDelayed(TOPREAL_HIDE_FINGERPRINT,
    mCurFingerPrintTask.getFingerPrintShowDuration() * 1000);
        break;
    
    case TOPREAL_HIDE_FINGERPRINT:
        toprealFingerDialog.dismiss();
        if(mCurFingerPrintTask.isFinish()) {
            if(!fingerPrintTaskQueue.isEmpty()) {
                try {
                    mCurFingerPrintTask = fingerPrintTaskQueue.dequeue();
                    toprealFPTimer.schedule(mCurFingerPrintTask, 0,
                        (mCurFingerPrintTask.getFingerPrintFadeDuration() + mCurFingerPrintTask.getFingerPrintShowDuration()) * 1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else {
                mCurFingerPrintTask = null;
            }
        }
        break;
    
    • 实现的效果如需求所示,显示fingerprint持续时间+间隔时间为一个周期,规定显示次数,如果达到则从TaskQueue中取一个Task继续执行。大致思想就是这样

    相关文章

      网友评论

          本文标题:Timer实现周期任务队列的调度

          本文链接:https://www.haomeiwen.com/subject/kmjycqtx.html