如何在 Android 中的非 UI 线程上执行延迟

How to perform a delay on a non-UI Thread in Android

因此,关于如何在 Android 上进行延迟,有多个类似的 questions/answers。然而,他们主要专注于在 UI 线程上执行此操作。 如果我需要延迟服务中的工作线程(并且我不想让该线程休眠)怎么办? Handler.postDelayed() 不起作用,因为存在 "can't create a handler inside thread has not called Looper.prepare()" 异常。出于同样的原因,CountDownTimer 不起作用。而且我没有任何视图可以调用 运行OnUiThread()。 那么是在我拥有的每个线程上都有一个循环程序的唯一解决方案还是有另一种方法可以做到这一点?

更新: 这很愚蠢,但我在自己的旧代码中找到了对我有用的答案:)。 基本上,如果你想从一个非UI线程延迟启动一个Runnable,你需要做的就是让主循环器来处理这个。

    Handler handler = new Handler(Looper.getMainLooper());
    Runnable r = new Runnable() {

        @Override
        public void run() {
        // Do stuff to be run after a delay
        // CAUTION: this won't be run on the same thread
        }
    };
    handler.postDelayed(r, DELAY_TIME); 

缺点可能是 Runnable 中的代码不会 运行 在与原始代码相同的线程上。这就是为什么我不把这种方法作为一个被接受的答案(我承认,最初的问题听起来像是我想要一个定时事件发生在同一个非 UI 线程上。为此我不除了来自 Emmanuel 的那个我必须在我的线程上附加一个 Looper 之外,还有一个答案)。然而,出于我的目的,这是可行的,因为我只需要在超时时启动服务。

就像您在 Exceptions 中看到的那样,为了在 Thread 中使用 Handlers,您需要将 Thread 附加到 Looper。为了提供更多上下文,当您调用 postDelay() 时,您正在向 ThreadMessageQueue 发送消息; Looper 负责管理此 Queue。因此,如果您想走 Handler 路线,则需要使用 Looper.

设置 Thread

如果你想延迟 Thread 而不是 sleep() (我不知道为什么你不能使用 sleep())你可以有一个 while 运行直到从现在开始经过一定时间。 (这听起来像是一个可怕的想法)。