阻塞延迟 android,Android三种延时执行方式对比

在android中经常会有延时执行的需求。这里对比一下几种延时执行实现方式的优劣。

1、Handler

通过Handler的postDelayed来实现延时

Integer time = 2000;

Handler handler = new Handler();

handler.postDelayed(new Runnable() {

@Override

public void run() {

Intent intent = new Intent(LaunchActivity.this,MainActivity.class);

startActivity(intent);

LaunchActivity.this.finish();

}

},time);

Handler的源码位于**/frameworks/base/core/java/android/os/Handler.java**,postDelayed通过调用sendMessageDelayed、sendMessageAtTime、enqueueMessage,来到MessageQueue类的enqueueMessage方法:

boolean enqueueMessage(Message msg, long when) {

if (msg.target == null) {

throw new IllegalArgumentException("Message must have a target.");

}

if (msg.isInUse()) {

throw new IllegalStateException(msg + " This message is already in use.");

}

synchronized (this) {

if (mQuitting) {

IllegalStateException e = new IllegalStateException(

msg.target + " sending message to a Handler on a dead thread");

Log.w(TAG, e.getMessage(), e);

msg.recycle();

return false;

}

msg.markInUse();

msg.when = when;

/*postDelayed最后就是把Message的when设置为延迟的时间,然后插入MessageQueue,交给looper去执行;此时的阻塞是会释放cpu资源的,下面的代码主要用于唤醒。

*/

Message p = mMessages;

boolean needWake;

if (p == null || when == 0 || when < p.when) {

// New head, wake up the event queue if blocked.

msg.next = p;

mMessages = msg;

needWake = mBlocked;

} else {

// Inserted within the middle of the queue. Usually we don't have to wake

// up the event queue unless there is a barrier at the head of the queue

// and the message is the earliest asynchronous message in the queue.

needWake = mBlocked && p.target == null && msg.isAsynchronous();

Message prev;

for (;;) {

prev = p;

p = p.next;

if (p == null || when < p.when) {

break;

}

if (needWake && p.isAsynchronous()) {

needWake = false;

}

}

msg.next = p; // invariant: p == prev.next

prev.next = msg;

}

// We can assume mPtr != 0 because mQuitting is false.

if (needWake) {

nativeWake(mPtr);

}

}

return true;

}

所以,通过Handler来设置延迟并不会占用CPU的资源。

2、TimerTask

创建一个TimerTask,交给Timer的schedule执行:

TimerTask task = new TimerTask() {

@Override

public void run() {

Intent intent = new Intent(LaunchActivity.this,MainActivity.class);

startActivity(intent);

LaunchActivity.this.finish();

}

};

Timer timer = new Timer();

timer.schedule(task, 2000);

这种实现基于Timer类,而Timer的实现则是通过内部开启一个TimerThread,TimerThread在run方法中调用mainLoop:

/**

* The main timer loop. (See class comment.)

*/

private void mainLoop() {

while (true) {

try {

TimerTask task;

boolean taskFired;

synchronized(queue) {

// Wait for queue to become non-empty

while (queue.isEmpty() && newTasksMayBeScheduled)

queue.wait();

/*这里可以看到,就是通过wait等待,然后notify唤醒来实现延迟*/

if (queue.isEmpty())

break; // Queue is empty and will forever remain; die

// Queue nonempty; look at first evt and do the right thing

long currentTime, executionTime;

task = queue.getMin();

synchronized(task.lock) {

if (task.state == TimerTask.CANCELLED) {

queue.removeMin();

continue; // No action required, poll queue again

}

currentTime = System.currentTimeMillis();

executionTime = task.nextExecutionTime;

if (taskFired = (executionTime<=currentTime)) {

if (task.period == 0) { // Non-repeating, remove

queue.removeMin();

task.state = TimerTask.EXECUTED;

} else { // Repeating task, reschedule

queue.rescheduleMin(

task.period<0 ? currentTime - task.period

: executionTime + task.period);

}

}

}

if (!taskFired) // Task hasn't yet fired; wait

queue.wait(executionTime - currentTime);

}

if (taskFired) // Task fired; run it, holding no locks

task.run();

} catch(InterruptedException e) {

}

}

}

TimerTask实现延迟的方式会新起一根线程,通过线程的wait和notify来实现延迟。

3、Thread

可以通过设置Thread的sleep来实现延迟:

new Thread() {

@Override

public void run() {

super.run();

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

Intent intent = new Intent(LaunchActivity.this,MainActivity.class);

startActivity(intent);

LaunchActivity.this.finish();

}

}.start();

这种方式也会新起一根线程。

总结

三种方式,显然Handler的开销更小,TimerTask和Thread.sleep都需要新起线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值