2014-12-24 5 views
1

나는 ListView가있는 조각이있는 앱을 가지고 있습니다. 네트워크상의 IP 주소를 핑 (ping)하고 응답을 받으면 IP 주소를 목록에 추가합니다. 일단 IP 주소를 ping하고 나면, 핑 (ping)에 응답 한이 IP 주소 목록을 ListView에 넣습니다.조각에서 백그라운드 스레드에서 UI를 업데이트하는 방법

내가하고 싶은 일은 모든 IP 주소를 핑 (ping) 한 후에 핑 (ping)하고 있기 때문에이 ListView를 업데이트하는 것입니다. IP 주소를 Ping하려면 AsyncTask를 사용하여 Runnable Thread를 호출합니다. IP 주소를 찾으면 그 Runnable 클래스에서 UI를 업데이트하도록 Fragment에 어떻게 알리는가?

내 수업의 대략적인 레이아웃은 다음과 같습니다.

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'을 시도했습니다 오버라이드 (override) 방법으로 그것을 잡을? –

+0

대신 핸들러를 사용하십시오. google sample.https의 threadSample 예제를 참조하십시오. //developer.android.com/training/multiple-threads/communicate-ui.html – mcd

답변

0

사용 처리기, runOnUiThread 또는 View.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을 사용한다! 기본 UI 스레드에서 실행되는 방법 onPostExecute()은 UI를 업데이트 할 수있는 지점입니다 ...

하지만 AsyncTask (스레드도)를 취소해야한다는 점을 명심해야합니다 if 조각이 파손되면 그렇지 않으면 작업이 계속 실행되고 조각의 UI를 변경하려고 시도하지만 조각이 더 이상 존재하지 않아 예외로 이어질 수 있습니다. IllegalStateException: Fragment not attached to Activity 또는 View Not Attached Exceptions

+0

나는 그 순간에 그렇게하고있다. onPostExecute()를 사용하지만 doInBackground가 완료되면 ListView가 업데이트됩니다.doInBackground가 실행되는 동안 ListView를 업데이트하려고합니다. – user2144072

+1

wtf? 분명히 당신은'doInBackground()'에서 작업을하고 나중에 onPostExecute()에서 목록을 업데이트합니다. 당신이 "ListView 한 번 doInBackground()"를 업데이트하는 것이 무슨 뜻인지 모르겠다 ... 20 개의 AsyncTasks를 실행할 수 있고 각각은 doInBackground()에서 데이터를로드하고 나중에 onViewExecute()에서 ListView를 업데이트하거나 20 번 findDevices를 실행하는 단일 AsyncTask를 작성할 수 있으며, onInitground()에서 UI를 부분적으로 업데이트 할 수있는 AsyncTasks'onProgressUpdate()'를 사용할 수 있습니다. 여기서'onPostExecute() '는 한 번만 호출됩니다. 모두 – sockeqwe

1

시도해보십시오.

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

처리기 클래스 사용은 좋은 습관입니다. –

1

Handler, runOnUiThread, postDelayedAsyncTask.
AsyncTask은 핸들러 클래스를 확장하므로 rest가 아닌 다른 좋은 옵션입니다. 자동 업데이 트를 매 X 초 당신에

new MyAsyncTask().execute(); 
0

당신이 원하는 경우 :

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

을 그리고이 같은 UI 스레드에서 호출 : 당신이 스레드 코드에있을 때
이 같은 doInBackground() 방법을 사용 이것을 사용할 수 있습니다 :

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()

@Override 
protected void onProgressUpdate(Void... values) { 
    super.onProgressUpdate(values); 
} 
관련 문제