Android/Java - 使用处理程序或调度程序延迟 Runnables?

Android/Java - Delaying Runnables using Handlers or Scheduler?

我正在尝试找到一种方法让一个线程 运行 持续 2 秒,另一个线程 运行 持续 3 秒。我正在使用下面的 运行nables:

    private Runnable setLocation, checkWriteAttempt;

{
    setLocation = new Runnable() {
        @Override
        public void run() {
            // Get Location
            String location = FM.getLocation(SingletonSelectedMAC.getMAC());
            Log.e("Lockdown Pin", "Room Number = " + location);
            mConfirm.setEnabled(false);
            mCancel.setEnabled(false);
        }
    };

    checkWriteAttempt = new Runnable(){
        @Override
        public void run(){

            if(SingletonWriteData.getWasDataWritten()){
                startAlertActivity();
            }
            else{
                restartActivity();
            }

        }
    };
}

为了启动线程,我调用下面的方法 "attemptToWriteData"。

我最初的尝试是使用将使用 postDelayed 的处理程序 运行 线程一段时间。但是,运行nables "setLocation" 和 "checkWriteAttempt" 都会同时 运行,这对我的程序不起作用。除此之外,新的 activity 将启动并正常工作。

后来,我尝试使用ScheduledExecutor。然而,使用这种方法,我的 activity 不会在我的 android 设备上改变,并且当它们执行时我没有收到来自 运行nables 的 Log.e 输出。 运行nables 肯定会被调用,因为它们正在向我的蓝牙设备(灯)发送数据。见下文:

    public void attemptToWriteData(){
        scheduledExecutor.scheduleWithFixedDelay(setLocation, 0, 2, TimeUnit.SECONDS);
        scheduledExecutor.scheduleWithFixedDelay(checkWriteAttempt, 2, 3, TimeUnit.SECONDS);

        scheduledExecutor.shutdown();

        /*
        mHandler.postDelayed(setLocation, 2000);
        mHandler2.postDelayed(checkWriteAttempt, 3000);
        */
    }

两个线程都需要时间来处理来自蓝牙设备的背景信息(我从 运行nables 中省略了这部分,因为它与工作相关)。

提前感谢您的建议!

为了 运行 一个线程持续 2 秒,另一个线程持续 3 秒,您需要一种暂停线程的能力,因此必须将工作细分为多个部分,以便线程可以从他们离开的地方。

运行 每个固定秒数的任务更容易。您使用 ScheduledExecutor 的方法可能不起作用,因为您尝试更新 UI 而不是在主 android 线程上。

使用 RxAndroid 库尝试以下解决方案。您必须将 Runnable 转换为 Callable,以便它们 return 计算结果可用于更新 UI:

Observable<Integer> o = Observable.merge(
    Observable.interval(2, TimeUnit.SECONDS).map(t -> setLocation),
    Observable.interval(3, TimeUnit.SECONDS).map(t -> checkWriteAttempt)
)
.map(c -> c.call())
.subscribeOn(Schedulers.single())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(computationResult -> /*update UI here*/);

此代码将确保可调用对象不会 运行 并发并且 UI 更新是 运行 在主线程上。