2015-10-09 99 views
2

好吧,所以我知道如何做一個後臺任務,我知道如何做週期性的任務(使用handle postdelayed和runnable),我也知道如何從後臺線程(通過處理程序)做UI任務,但我不能執行定期後臺任務,在UI線程上執行一些操作。Android:創建一個定期運行並執行UI任務的後臺線程?

我想執行一些後臺任務,每分鐘我都必須進行網絡調用。通話結束後,根據輸出我必須更新UI。我試圖做這樣的事情

private void DoTask() { 
     Thread thread = new Thread() { 
      public void run() { 
       Looper.prepare(); 
       final Handler handler = new Handler(); 
       handler.post(netRunnable); 
       Looper.loop(); 
      } 
     }; 
     thread.start(); 
} 

Runnable netRunnable = new Runnable() { 
    @Override 
    public void run() { 
     handler.getLooper().prepare(); 
     final Handler handler1 = new Handler(Looper.getMainLooper()); 
     if (do background work and check result){ 
      handler1.post(new Runnable() { 
       @Override 
       public void run() { 
        //Do UI Task 
       } 
      }); 
     } 
     handler.getLooper().loop(); 
     handler.postDelayed(netRunnable, 60000); 
    } 
} 

據我瞭解,有可能是我的執行一些基本的缺陷,但我不知道如何正確地做這個任務。現在它給出的錯誤是Only one Looper may be created per thread。我得到它想說的。但任何人都可以請建議以正確的方式做到這一點。

+0

檢查此帖:http://stackoverflow.com/a/15472594/4516174 – yongsunCN

回答

1

也許你更好,創建一個單獨的(Intent)Service並定期使用postDelayed進行調用。在您的活動中創建一個BroadcastReceiver並處理那裏的UI更改。

處理來自其他線程的UI更改的另一個提示:這是不可能的。因此你需要調用runOnUiThread。 Here is how to use it

+0

意向服務是一個選項,但有兩個原因我不想使用它。首先,我不需要在應用程序處於後臺時執行任務,這是使用IntentService的主要原因。其次,我的需求是自我週期性運行的東西,我認爲它可以以更簡單的方式完成。無論如何感謝您的答覆。 – varunkr

2

您可以使用異步任務。這是專爲它:

http://developer.android.com/reference/android/os/AsyncTask.html

它可以讓你在後臺執行網絡電話,那麼當你得到的結果,UI線程

宣言執行動作

private class MyTask extends AsyncTask<Input, Void, Output> { 
protected Output doInBackground(Input... inputs) { 
     // do something on the network 
     return myOutput;// use this to transmit your result 
} 

protected void onPostExecute(Output result) { 
    // do something on UI thread with the result 
} 

}

如果你想再說一遍,只需創建一個可運行的啓動它,並且每次調用後,安排下一個上E:

MyTask myTask; 
Handler handler = new Handler(); 

    Runnable myRunnable = new Runnable() { 
      @Override 
      public void run() { 
       MyTask myTask = new MyTask(); 
       myTask.execute(myArg); 
       handler.postDelayed(netRunnable, 60000); // schedule next call 
      } 
     } 

要啓動它的第一次:

handler.postDelayed(myRunnable, 60000); 

或者,如果您要立即啓動它:

handler.post(myRunnable); 

不要忘記何時取消任務您活動被破壞:

myTask.cancel(true); 
+0

什麼如果您在asyncTask運行時旋轉手機? – AlbAtNf

+0

它取決於是否觸發配置更改事件。如果是這樣,該活動將被銷燬,並且AsyncTask需要被取消。如果沒有配置更改,活動不會被破壞,所以我認爲它是可以的。 –

+0

如果我看[this](http://stackoverflow.com/q/4748964/4791726),我認爲這個任務不會被輕易取消。您也可能會失去對有效活動的引用。取消網絡任務也可能不是最好的主意。 – AlbAtNf

0

如果活動頻繁切換,爲什麼不扭轉責任。您可能會創建一個執行週期性網絡任務的服務。

然後, - 您的活動定期調用此服務以獲取價值。 - 或者您使用偵聽器系統:您創建一個界面,您的活動必須執行以便從任務完成中獲得通知

相關問題