美文网首页
Handler.postDelay()的坑

Handler.postDelay()的坑

作者: FreedApe | 来源:发表于2018-11-23 15:46 被阅读0次

现在某些app,当你进入后台(BG)的情况下,过了特定的时间段,再从后台切换回来,就会在原来的页面上显示一个广告页面或者解锁页面或者其他特定的页面。

刚开始,我使用Handler.postDelay()的方式来实现这种效果,代码如下(也是参考别人的方法):

public class BaseApplication extends Application implements Application.ActivityLifecycleCallbacks {

    private boolean foreground;
    private boolean paused = true;
    private Handler handler = new Handler();
    private Runnable check;

    private Long pausedTime = 0L;
    private Long resumedTime = 0L;

    ....

    @Override
    public void onActivityResumed(Activity activity) {
        paused = false;
        boolean wasBackground = !foreground;
        foreground = true;
        if (check != null) {
            handler.removeCallbacks(check);
        }

        resumedTime = System.currentTimeMillis();
        LogUtils.outputLog("Test resumeTime " + resumedTime);
        LogUtils.outputLog("Test duration Time  " + (resumedTime - pausedTime));

        if (wasBackground) {
           // 显示特定页面
        }
    }

    @Override
    public void onActivityPaused(Activity activity) {

        paused = true;
        if (check != null) {
            handler.removeCallbacks(check);
        }

        pausedTime = System.currentTimeMillis();

        long delayTime = 1000 * 60;
        handler.postDelayed(check = () -> {
            if (foreground && paused) {
                foreground = false;  // app 在 BG 经过 1min 后,正常来说是应该触发这里。
            }
        }, delayTime);
    }
}

这段代码 在设备亮屏或者连接USB锁屏的情况下是没有问题的。

但是

当设备没有连接USB处于锁屏状态下,就出问题了.......postDelay 里面的 runnable 不会执行。

查看了Handler.postDelay的源码,如下:

 public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

发现是在 SystemClock.uptimeMillis() + delayMillis 时间点发送 msg,如果 SystemClock.uptimeMillis() 在特殊情况下,出现问题,这个msg 就不会发送出来了。

SystemClock.uptimeMillis()的源码:

    /**
     * Returns milliseconds since boot, not counting time spent in deep sleep.
     *
     * @return milliseconds of non-sleep uptime since boot.
     */
    @CriticalNative
    native public static long uptimeMillis();

注意这个方法的注释:Returns milliseconds since boot, not counting time spent in deep sleep.
说的是睡眠模式下的时间不会进行计算。

我在onActivityResumed和onActivityPaused 分别对SystemClock.uptimeMillis()进行 log 输出,如果要显示解锁页面,SystemClock.uptimeMillis() + delayMillis应该是大于 10836078 + 60000 = 10896078,但是实际当时间过去3min后,却是10872205

11-15 15:59:05.829 25137-25137/YourAppName: Test PausedTime 1542265145829
11-15 15:59:05.829 25137-25137/YourAppName: Test time(onActivityPaused):10836078-->SystemClock.uptimeMillis()
11-15 16:04:52.218 25137-25137/YourAppName: Test resumeTime 1542265492217
11-15 16:04:52.218 25137-25137/YourAppName: Test time(onActivityResumed):10872205-->SystemClock.uptimeMillis()
11-15 16:04:52.218 25137-25137/YourAppName: Test duration Time  346388

所以handler.postDelay不是 所有情况下都合适的。对之前的代码进行了改动:

public class BaseApplication extends Application implements Application.ActivityLifecycleCallbacks {

    private Long pausedTime = 0L;
    private Long resumedTime = 0L;

    @Override
    public void onActivityResumed(Activity activity) {
        resumedTime = System.currentTimeMillis();
        boolean wasBackground = false;
        long delayTime = 1000 * 60;
        if ((resumedTime - pausedTime) > delayTime) {
            wasBackground = true;
        }

        if (wasBackground) {
        .....
        }
    }

    @Override
    public void onActivityPaused(Activity activity) {
        pausedTime = System.currentTimeMillis();
    }
}

以上。

相关文章

  • Handler.postDelay()的坑

    现在某些app,当你进入后台(BG)的情况下,过了特定的时间段,再从后台切换回来,就会在原来的页面上显示一个广告页...

  • Handler.postDelay 较长时间的任务可能不执行的问

    最近有个功能需求,要做一个延时任务 当时图简单,就直接用Handler.postDelay做了 结果测试发现一旦延...

  • 坑说

    大坑小坑,皆是坑; 深坑浅坑,都能坑; 能不被坑,别被坑; 休要日日想被坑。 关于坑古来有之,最近的就是坑爹,远的...

  • 白童话 | 标题待定

    日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日更占坑日...

  • 2018-02-08

    坑爹,坑娘。还没见过坑儿子的

  • WebView上传文件无响应的问题:

    坑,坑,坑,坑,坑,坑;注意事项:做完这些可能调用系统相册是没有问题的,但是如果自己写的一个选择图片的页面,我们通...

  • 小马啊小马

    马化腾坑写手,马云坑消费者,马明哲坑全家,马蓉坑老公,马俊仁坑田径,马航坑乘客,马谡坑诸葛亮,马夫人坑乔峰,马伯庸...

  • 汽车坑 | 贷款买车坑不少 你被坑了吗?

    本文转载自公众号“汽车坑”(ID:qichekeng),“汽车坑,大坑小坑,和坑主一起入坑出坑” 今天,坑主有一朋...

  • 奇太公钓鱼,愿者入坑~

    PS:圈坑、壁坑、抽坑......

  • 画画练习 | 画画练习 #63

    还在加班,占个坑,还在加班,占个坑,还在加班,占个坑,还在加班,占个坑,还在加班,占个坑,还在加班,占个坑,还在加...

网友评论

      本文标题:Handler.postDelay()的坑

      本文链接:https://www.haomeiwen.com/subject/vgvjqqtx.html