2015-09-21 49 views
1

我正在使用ScheduledExecutorService來定期運行Runnable。在Runnable中,我註冊了一個SensorEventListener。我注意到在主線程上調用了SensorEventListener回調函數,而不是ScheduledExecutorService的線程池中的線程。我想處理主線程傳感器事件的回調。看起來我能夠在調用SensorManager類的registerListener()時傳遞Handler對象,並且回調函數將在Handler所來自的線程上運行。使用ExecutorService時獲取對處理程序的引用

有沒有辦法獲得對ScheduledExecutorService的Handler的引用?

回答

3

這很難。常規ExecutorService沒有Looper,在這樣的線程中不能有Handler

A Looper是一個無限循環,可以將隊列出隊並執行事件。所以如果你安排你的執行者被阻止。你可以基於Looper的事件處理來實現你自己的執行器,但我想這不是你想要的。

要從後臺使用傳感器,您需要創建HandlerThread。這是一個運行Looper的後臺線程,因此它可以有一個Handler

小例子

private HandlerThread mHandlerThread; 
private Handler mBackgroundHandler; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mHandlerThread = new HandlerThread("SomeNameHere"); 
    mHandlerThread.start(); 
    mBackgroundHandler = new Handler(mHandlerThread.getLooper()); 

    mBackgroundHandler.post(new Runnable() { 
     @Override 
     public void run() { 
      // I can do blocking network here. 
     } 
    }); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    mHandlerThread.quitSafely(); 
} 
+1

好這就是我最終做的。每10秒我想爲SensorEvenListener記錄2秒鐘的樣本。我最終制作了一個HandlerThread並獲得了一個參考。到其處理程序並在註冊期間將其傳遞到SensorManager。 HandlerThread然後接收回調事件並將這些值添加到列表中。我保留了Scheduled ExecutorService,每10秒鐘運行一次可以註冊傳感器事件的runnable,休眠2秒鐘(在這段時間內HandlerThread隊列中的值),然後喚醒傳感器事件的取消註冊並在db中緩存值。謝謝! – neonDion

0

您可以在後臺線程(其中您的ScheduledExecutorService正在運行)中嘗試Handler handler = new Handler(Looper.myLooper());,然後將實例傳遞給SensorManager

0

處理程序總是在它創建的線程中「處理」東西,因此只需在您的ExecutorService中創建一個新東西。只需使用default Handler constructor

+0

然後http://stackoverflow.com/questions/3875184/cant-create-handler-inside-thread-that-has-not-called-looper-prepare發生 – zapl

相關問題