2012-06-26 35 views
-1

我有一張地圖,我想從一個單獨的線程進行更新。當我嘗試從擴展asynctask的類中更新UI時,我遇到了一些問題。當我將代碼移到主線程中的處理程序時,我得到NetworkOnMainThreadException。下面是我的asynctask。有沒有什麼辦法可以修改它以使其工作?網絡+ UI更新,asynctask vs處理程序

@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中保留對您的Activity的引用,否則可能導致內存泄漏。

理想情況下,您應該創建一個可以將數據返回到您的活動的觀察者。

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

非常感謝。如果我只是將我的userlist作爲返回值並在主線程中使用'task.execute.get()',然後在同一線程中更新ui,會發生什麼?餿主意? :) – Johan