Timer实现周期任务队列的调度
2018-12-03 本文已影响0人
Spirituality韬
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继续执行。大致思想就是这样