2014-12-24 152 views
1

我有一個應用程序具有帶ListView的片段。我ping網絡上的IP地址,當我得到響應時,我將IP地址添加到列表中。一旦我完成了對IP地址的ping操作,我就把這個列表中的IP地址回覆給了我的ping。如何從片段中的後臺線程更新UI

我想要做的就是更新這個ListView,因爲我在ping所有IP地址之後ping而不是做。要ping IP地址,我使用AsyncTask,然後調用Runnable Thread。當我找到IP地址時,如何告訴Fragment從該Runnable類更新UI?

我的課程大致佈局如下。

public class FinderFragment extends ListFragment { 

    private void CallFind(){ 
     new Find().execute(); 
    } 

    private class Find extends AsyncTask<Void, Void, Void> { 

     @Override 
     protected Void doInBackground(Void... voids) { 
      SearchNetwork searchNetwork = new SearchNetwork(ipAddress); 
      try { 
       searchNetwork.StartFind(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      UpdateDeviceList(); 
     } 
    } 
} 

public class SearchNetwork { 

    public void StartFind() throws InterruptedException { 
     Thread t[] = new Thread[20]; 
     for(int i=0; i<02; i++){ 
      t[i] = new Thread(new FindDevices(i*5)); 
      t[i].start(); 
     } 
     for(Thread thread : t){ 
      thread.join(); 
     } 
    } 

    class FindDevices implements Runnable{ 

     @Override 
     public void run() { 
      //Ping the IP addresses here 
      //I want to update UI from here 
     } 
    } 
+0

你試過'getActivity()。runOnUiThread'? –

+0

使用處理程序而不是它請參閱谷歌示例的threadSample示例.http://developer.android.com/training/multiple-threads/communicate-ui.html – mcd

回答

0

使用處理器runOnUiThreadView.post

android.os.Handler handler = new android.os.Handler(); 
     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       //update here 
      } 
     }); 
+0

對不起,我只是真的開始學習線程和AsyncTasks並且仍然不完全理解它們。那個處理程序會放在我的FinderFragment類中嗎? – user2144072

+1

是的,他可以從任何線程。 – SorryForMyEnglish

1

您應該使用AsyncTask代替原紗的!有一種方法onPostExecute()在主UI線程上運行,這就是您可以更新UI的點...

但是您必須記住,您必須取消AsyncTask(線程以及)if片段被破壞,否則你的任務將繼續運行,並會嘗試更改片段的UI,但片段不再存在,這將導致例外IllegalStateException: Fragment not attached to ActivityView Not Attached Exceptions

+0

我現在正在這樣做。我使用onPostExecute(),但doInBackground完成後更新ListView。我想在doInBackground運行時更新ListView。 – user2144072

+1

wtf?很明顯,你在'doInBackground()'中做了你的工作,然後在'onPostExecute()'中更新列表。我不知道你的意思是「更新ListView一次doInBackground()」...你可以運行20個AsyncTasks,並且每個都在'doInBackground()'中加載數據,然後在'onPostExecute()'中更新ListView,或者你可以編寫一個AsyncTask,它將運行20次findDevices並使用AsyncTasks'onProgressUpdate()',它允許您從doInBackground()中部分更新UI(在主UI線程上運行),其中onPostExecute()全部 – sockeqwe

1

試試這....

getActivity().runOnUiThread(new Runnable(){ 
      @Override 
      public void run(){ 
       // Do whatever you want 
       } 
      }); 
+0

使用Handler類是很好的做法 –

1

我們可以使用HandlerrunOnUiThreadpostDelayedAsyncTask
AsyncTask除了休息之外是個不錯的選擇,因爲它擴展了處理程序類。
當您在線程必須代碼使用doInBackground()方法是這樣的:

class myAsyncTask extends AsyncTask(Void,Void,Void){ 
    public doInBackground(){ 
     // do your code here 
    } 
} 

,並調用它的UI線程這樣的:

new MyAsyncTask().execute(); 
0

,如果你想自動更新每隔x秒你可以使用此:

Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      while(refreshing){ 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         //do your stuff here 
        } 
       }); 
       try{ 
        Thread.sleep(30000); 
       }catch(InterruptedException e){ 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 
    new Thread(runnable).start(); 
0

嘗試

publishProgress()

,並抓住它在overidden方法

@Override 
protected void onProgressUpdate(Void... values) { 
    super.onProgressUpdate(values); 
}