在Andoird中,有时候对某一个操作进行延时处理, 如果在短时间内多次调用希望只执行一次。如快速点击拨号按钮,我们希望只拨号一次即可。以下为本人对此做的一些总结。
方法一:采用Handler的postDelayed方法来进行延时操作
private void testMethod(){
}
Runnable sRunable = new Runnable() {
@Override
public void run() {
testMethod();
}};
private Handler mHandler1 = new Handler();
/**
* 优点:在指定的时间内(100ms)只执行一次 testMethod()方法
* 缺点:消耗的内存较多
*/
public void test1() {
mHandler1.removeCallbacks(sRunable);}
mHandler1.postDelayed(sRunable, 100);
方法二:采用Handler的sendMessageDelayed方法来进行延时操作
private final static int MESSAGE_ONE = 0x0001;
private void testMethod(){
}@SuppressLint("HandlerLeak")
private Handler mHandler2 = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ONE:
testMethod();
break;
default:
break;
}
};};
/**
* 优点:在指定的时间内(100ms)只执行一次 testMethod()方法,开销比较小
*/
public void test2() {
Message msg = new Message();}
msg.what = MESSAGE_ONE;
mHandler2.removeMessages(MESSAGE_ONE);
mHandler2.sendMessageDelayed(msg, 100);
// 或者用下面方式,两个效果相同
mHandler2.removeMessages(MESSAGE_ONE);
mHandler2.sendEmptyMessageDelayed(MESSAGE_ONE, 100);
方法三:采用互斥的方式防止testMethod()方法在未完成时被多次调用
/**
* 优点:能第一时间执行testMethod()方法,延时操作防止方法执行之后
* 注意:一定要在finally中将标志位恢复,否则testMethod()方法中出错后,将再不能执行此方法
*/
@SuppressLint("HandlerLeak")
private Handler mHandler3 = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ONE:
flags = true;
break;};
default:
break;
}
};
static boolean flags = true;
public void test3() {
try{
if(!flags){
return;
}else{
flags = false;
}testMethod();
}finally{
mHandler3.sendEmptyMessageDelayed(MESSAGE_ONE, 100);
}}
总结:以上三种方式中以第三种最优,即能第一时间相应调用事件,又能防止短时间内被多次调用
以下为另外两只实现延时处理的方法:
方法一:采用定时器延时
/**
* 优缺点:多次调用test4()会多次执行testMethod()*/
private Timer mTimer;
private TimerTask mTimerTask;
public void test4() {
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
testMethod();}
};
// 开始一个定时任务
mTimer.schedule(mTimerTask, 100);
}
/**
* 缺点:浪费时间,短时间多次运行会多次执行testMethod()方法
*/
public void test5() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}}
testMethod();