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

时间:2017-08-07 10:56:48

标签: java multithreading android-studio scheduler runnable

我试图找到一种方法让一个线程运行2秒,另一个运行3秒钟。我正在使用以下runnables:

    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运行线程一段时间的处理程序。但是,runnables“setLocation”和“checkWriteAttempt”都会同时运行,这对我的程序不起作用。除此之外,新活动将开始并正常运作。

后来,我尝试使用ScheduledExecutor。但是,使用这种方法,我的活动不会在我的Android设备上更改,并且在执行时我没有收到runnables的Log.e输出。正在调用runnables因为他们正在向我的蓝牙设备发送数据(灯光)。见下文:

    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);
        */
    }

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

提前感谢您的建议!

1 个答案:

答案 0 :(得分:0)

为了运行一个线程2秒而另一个线程运行3,你需要能够暂停你的线程,因此必须将工作细分为多个部分,以便线程可以从它们停止的位置开始。

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

使用RxAndroid库尝试以下解决方案。您必须将Runnable转换为Callable,以便它们返回可用于更新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*/);

此代码将确保callables不会并发运行,并且UI更新在主线程上运行。