AndroidL 操作延时的方法

在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);

    }

 


方法二:采用Thread的sleep方法来延时
/**
 * 缺点:浪费时间,短时间多次运行会多次执行testMethod()方法
 */
public void test5() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
testMethod();
}
### Kotlin 中实现延迟执行或定时任务 #### Handler 的使用 在 Android 平台下,`Handler` 是一种常见的用于处理消息和运行代码片段的方式。通过 `postDelayed()` 方法可以在指定的时间之后执行一段代码。 ```kotlin val handler = Handler(Looper.getMainLooper()) handler.postDelayed({ // 这里放置要延迟执行的代码 }, 1000) // 延迟时间为1000毫秒即1秒[^1] ``` #### 协程中的延时操作 利用 Kotlin 的协程库 (`kotlinx-coroutines`) 可以更加简洁高效地完成异步编程工作。其中包含了专门用来做短暂休眠而不阻塞线程的功能——`delay()` 函数,在不消耗额外资源的情况下实现了精准计时等待的效果。 ```kotlin import kotlinx.coroutines.* GlobalScope.launch { println("开始") delay(1000L) // 挂起当前协程并暂停其执行直到经过给定数量的毫秒 println("结束") } ``` #### 使用 Flow 来创建周期性的事件流 对于需要定期发出新值的情况,比如轮询服务器获取最新状态更新 UI 界面等场合,则可以考虑采用 `Flow` 结合 `interval()` 或者其他类似的算子来构建这样的逻辑链路。 ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking<Unit> { launch { (1..5).asFlow() .onEach { value -> println(value) } .collect() interval(1000) // 创建一个无限发射整数序列的冷流,每次间隔一秒发射下一个数值 .take(5) // 获取前五个元素后停止收集 .collect { value -> println("Tick $value") } } Thread.sleep(6_000) // 让主线程保持活跃以便观察输出结果 } ``` #### Java Util Timer 类的应用 除了上述现代风格的做法之外,传统上还可以借助于标准库提供的工具类如 `Timer` 和 `TimerTask` 组合起来达到相同的目的;不过需要注意的是这种方式相对较为笨重,并且存在潜在的风险点,例如如果应用退出时不取消已经安排好的计划可能会造成内存泄露等问题。 ```kotlin // 延迟一段时间后再执行特定动作 Timer().schedule(object : TimerTask() { override fun run() { // 执行具体业务逻辑... } }, 2000) // 此处设置为两秒钟后的触发时刻[^3] // 设置重复性调度策略 Timer().scheduleAtFixedRate(object : TimerTask() { var count = 0 override fun run() { if (++count >= 5) cancel() // 达到五次就终止循环 Log.d("TAG", "run: ") } }, 0, 1000) // 初始无延迟启动,随后每隔一秒钟再次调用一次回调方法 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值