抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

Android SystemClock.sleep() 的使用姿势

无意中看到了这个方法,觉得有点意思,记录一下。

先说结论:SystemClock.sleep() 本质上和 Thread.sleep()是没什么区别的,但有点特殊作用。

完整源码(位于 android.os 包下):

/**
* Waits a given number of milliseconds (of uptimeMillis) before returning.
* Similar to {@link java.lang.Thread#sleep(long)}, but does not throw
* {@link InterruptedException}; {@link Thread#interrupt()} events are
* deferred until the next interruptible operation. Does not return until
* at least the specified number of milliseconds has elapsed.
*
* @param ms to sleep before returning, in milliseconds of uptime.
*/
public static void sleep(long ms)
{
long start = uptimeMillis();
long duration = ms;
boolean interrupted = false;
do {
try {
Thread.sleep(duration);
}
catch (InterruptedException e) {
interrupted = true;
}
duration = start + ms - uptimeMillis();
} while (duration > 0);

if (interrupted) {
// Important: we don't want to quietly eat an interrupt() event,
// so we make sure to re-interrupt the thread so that the next
// call to Thread.sleep() or Object.wait() will be interrupted.
Thread.currentThread().interrupt();
}
}

可以看到大概做了什么,就是延迟,目的是为了保证睡够多少 ms,为什么要这么做呢?先看看平时 Thread.sleep 的用法。

val thread = object : Thread() {
    override fun run() {
        while (true) {

            if (isInterrupted) {
                //原有中断逻辑
                return
            }

            try {
                sleep(3000)
            } catch (e: Exception) {
                e.printStackTrace()
                //自行判断是否需要返回 或者继续
            }
        }
    }
}
thread.interrupt()

很简单的代码,Kotlin 中没有限制说 sleep 一定要 catch 住,但 Java 里这种事儿就挺常见,为啥呢?

就是为了防止睡眠过程中被中断了,然后影响逻辑,如果出现异常后直接 return,那么原有的中断逻辑就废了,如果不处理,那就是直接唤醒了线程然后继续任务,这次中断作废。这两者实际上都不是那么友好。所有有了 SystemClock.sleep()。这是 Android 老大哥做的,Java 里可找不到~

其目的是为了在 sleep 时收到中断事件后,继续睡眠,等待【逻辑上】的正常唤醒后再执行一次中断,这样可以确保线程中断时走的是原有的中断逻辑。

val thread = object : Thread() {
    override fun run() {
        while (true) {

            if (isInterrupted) {
                //原有中断逻辑
                return
            }

            SystemClock.sleep(3000)
        }
    }
}
thread.interrupt()

在对老旧代码改造的时候或许需要注意一下这些东西~ 写一写增加印象。


0条评论

发表评论