2012-06-26 4 views
-1

별도의 스레드에서 업데이트하려는 맵이 있습니다. 임 asynctask 확장 내 클래스에서 UI를 업데이트하려고하면 몇 가지 문제가 있습니다. 그리고 코드를 메인 스레드의 핸들러로 옮기면 NetworkOnMainThreadException이됩니다. 아래는 내 asynctask입니다. 작동하도록 수정하는 방법이 있습니까?네트워크 + ui 업데이트, asynctask 대 핸들러

@Override 
    protected Integer doInBackground(Void... params) { 

     try { 

      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost("http://83.xx.xx:8080/android/service.php"); 

      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
      nameValuePairs.add(new BasicNameValuePair("action", "getusers")); 
      nameValuePairs.add(new BasicNameValuePair("interval", Integer.toString(interval))); 

      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

      HttpResponse response = httpclient.execute(httppost); 

      String jsonString = EntityUtils.toString(response.getEntity()); 

      Gson gson = new GsonBuilder().create(); 

      Type listType = new TypeToken<ArrayList<User>>() {}.getType(); 
      ArrayList<User> userList = gson.fromJson(jsonString, listType); 

      ((GoogleMapsActivity) activity).removeOverlayItems(); 

      for(User user : userList){ 

       ((GoogleMapsActivity) activity).addOverlayItem(Double.parseDouble(user.last_lat), Double.parseDouble(user.last_lng), user.bluetooth_name, "test desc"); 
      } 


      return 1; 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 

답변

1

doInBackground에서지도를 터치하는 대신 데이터를 onPostExecute로 반환하십시오. 그런 다음 onPostExecute에서지도를 업데이트하십시오.

AsyncTask 내부에서 작업에 대한 참조를 절대로 저장하지 마십시오. 메모리 누수가 발생할 수 있습니다.

이상적으로는 활동에 데이터를 반환 할 수있는 옵저버를 만들어야합니다.

interface Observer { 
    public void onMyDataAvailable(MyDataClass data); 
} 

그런 다음이 관찰자에 대한 참조로 AsyncTask를 인스턴스화합니다.

class MyAsyncTask extends AsyncTask ... 
    private Observer observer; 

    public MyAsyncTask(Observer observer) { 
     mObserver = observer; 
    } 

    public synchronized void onActivityDestroyed() { 
     mObserver = null; 
    } 

    public synchronized void onPostExecute(MyDataClass result) { 
     if (mObserver != null) { 
      mObserver.onMyDataAvailable(result); 
     } 
    } 

귀하의 활동의 onDestroy 메소드에서 onActivityDestroyed()를 호출했는지 확인하십시오. 그렇지 않으면 활동이 누출됩니다.

+0

좋아요, 답변 해 주셔서 감사합니다. asynctask에서 주 스레드로 데이터를 가져 오는 방법에 대한 예제를 보여줄 수 있습니까? – Johan

+0

물론입니다. 지금 내 의견을 업데이트하겠습니다. – WindyB

+0

고마워. 반환 값으로 내 사용자 목록을 전달하고 주 스레드에서'task.execute.get()'을 사용한 다음 동일한 스레드에서 UI를 업데이트하면 어떻게됩니까? 나쁜 생각? :) – Johan

관련 문제