2012-06-26 3 views
-1

У меня есть карта, которую я хочу обновить из отдельного потока. У меня возникают некоторые проблемы, когда я пытаюсь обновить пользовательский интерфейс моего класса, который расширяет асинтез. И когда я перемещаю код в обработчик в основном потоке, я получаю NetworkOnMainThreadException. Ниже моя асинтеза. Есть ли способ изменить его, чтобы заставить его работать?network + ui updates, asynctask vs handler

@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); 
     } 
    } 

Просто убедитесь, что вы вызываете onActivityDestroyed() из метода onDestroy вашей деятельности. В противном случае ваша активность будет протекать.

+0

Хорошо, спасибо за ответ. Не могли бы вы показать мне пример того, как извлекать данные из asynctask в основной поток? – Johan

+0

Абсолютно. Я сейчас обновлю свой комментарий. – WindyB

+0

Большое спасибо. Что произойдет, если я просто передаю свой список пользователей как возвращаемое значение и использую 'task.execute.get()' в основном потоке, а затем обновить ui в том же потоке? Плохая идея? :) – Johan

Смежные вопросы