2012-06-21 49 views
7

當我的應用程序進行回調時,我有相當多的工作要做(讀取&通過ORM庫和一些基於距離的計算來寫入SQL數據庫)。當然,我擔心不會阻止主UI線程,所以我一直在嘗試(不成功)來確定這是否是進行回調的線程。如果是這樣,我打算在進行回調時觸發AsyncTask執行上述所有工作。同樣的AsyncTask也會接收來自2個獨立活動類的事件。 (迴應用戶輸入等)onLocationChanged回調是在什麼線程上進行的?主UI線程?

圍繞此回調發現的很多討論似乎基於人們試圖更改實際接收回調的線程。這對我來說沒有意義。當然平臺決定了這個回調的上下文,當接收到這個回調時,明智的做法是將任何嚴肅的工作轉移到另一個線程上,而AsyncTask似乎是合適的。

如果任何人都可以勾畫出他們在這裏使用過的成功模式,那將會非常有用。

回答

7

根據用於LocationManager Android的參考文檔:

調用線程必須是一個彎針線如 呼叫Activity主線程。

這意味着初始化回調的線程必須是主線程或線程的Looper

我發現處理此問題的最佳方法是在主線程上註冊一個OnLocationChanged接收器。然後,在我的回調中,我將創建一個Runnable以發送到後臺線程,在那裏執行任何長時間運行的任務(如寫入數據庫)。

ExecutorService mThreadPool = Executors.newSingleThreadExecutor(); 

@Override 
public void onLocationChanged(Location location) { 
    mThreadPool.execute(new Runnable() { 
     @Override 
     public void run() { 
      // Perform your long-running tasks here. 
      //... 
     } 
    }); 
} 
+0

從文檔看來,重新調用onLocationChanged的線程取決於傳遞給使用requestLocationUpdate(..)調用的參數。另外,如果Looper不是其中一個參數,那麼回調將在主UI線程的上下文中進行。需要閱讀更多關於Loopers的信息。上面的解決方案看起來很明智。我現在想知道它在性能方面與使用AsyncTask的比較。所以我會去閱讀文檔,因爲我應該首先完成文檔。謝謝您的幫助。 –

+0

你說得對,有幾個選項可以用來註冊一個LocationListener回調函數。閱讀文檔是絕對推薦的。上述解決方案大致相當於使用'AsyncTask'。我相信如果你看看AsyncTask類的源代碼,你會發現它在內部使用了一個'ExecutorService'。但是,如果您在任務完成時不需要與UI線程交互,則會發現「AsyncTask」的功能超出您的需求。 – twaddington

相關問題