2017-08-07 128 views
0

我試圖找到一種方法讓一個線程運行2秒,另一個運行3秒。我正在使用以下可運行的代碼:Android/Java - 使用處理程序或調度程序延遲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); 
     */ 
    } 

兩個線程需要時間來處理來自藍牙設備的背景信息(我從可運行,因爲它是與工作相關的省略該部分)。

非常感謝您的建議!

+0

請參閱https://stackoverflow.com/questions/2029118/run-code-for-x-seconds-in-java – Oleg

回答

0

爲了運行一個線程2秒和其他3個線程,您需要暫停線程的能力,因此必須將工作細分爲多個部分,以便線程可以從停止的地方接收數據。

每個固定的秒數運行任務更容易。您的ScheduledExecutor方法可能不起作用,因爲您嘗試更新UI而不是主要的Android線程。

使用RxAndroid庫嘗試以下解決方案。你將不得不轉換您RunnableCallable,使他們返回,可再用於更新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更新運行主線程。