2013-07-22 6 views
0

Я выполняю два экземпляра asyntask, один из них в onCreate, а другой - в обработчике onScroll. Цель приложения - загрузить через веб-сервисы X объем информации, а когда прокрутка идет вниз, продолжайте загружать информацию. Информация хорошо загружена, но иногда она продолжает загружаться, и приложение выходит из строя.Выполнение двух экземпляров asynctask в Android

Вот код doInBackground:

protected String doInBackground(String... args) { 
     // Declaro los parametros a enviar a la BD 
     cargando=true; 
     List<NameValuePair> params = new ArrayList<NameValuePair>(); 
     //parametro enviado (ciudad) 
     params.add(new BasicNameValuePair("ciudad", "5")); 
     params.add(new BasicNameValuePair("inicio", Integer.toString(inicio))); 
     params.add(new BasicNameValuePair("limite", Integer.toString(delante))); 

     JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params); 

     String def="default"; 

     // Check your log cat for JSON reponse 
     Log.d("All Products: ", json.toString()); 

     try { 
      // Checking for SUCCESS TAG 
      int success = json.getInt(TAG_SUCCESS); 

      if (success == 1) { 
       // products found 
       // Getting Array of Products 
       products = json.getJSONArray(TAG_PRODUCTS); 
       if (primeraEjecucion){ 
        String MAX = json.getString(TAG_MESSAGE); 
        totalConsultas=Integer.parseInt(MAX); 
       } 

       // looping through All Products 
       for (int i = 0; i < products.length(); i++) { 
        JSONObject c = products.getJSONObject(i); 

        String date = c.getString(TAG_DATE); 
        if (date.equals(def)){ 
         //tratar la fecha 
        } 
        else{ 
         boolean mostrarEvento=compararFechas(date); 
         if (mostrarEvento){ 
          Evento e=new Evento();              
          String id = c.getString(TAG_ID); 
          String name = c.getString(TAG_POST_TITLE); 
          String post = c.getString(TAG_POST); 
          String image = c.getString(TAG_IMAGE); 
          String place = c.getString(TAG_PLACE); 
          String category = c.getString(TAG_CATEGORY); 

          e.setID(Integer.parseInt(id)); 
          e.setTitulo(name); 
          e.setPost(post); 
          e.setImagen(image); 
          SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm"); 
          Date fecha1 = sdf.parse(date , new ParsePosition(0)); 
          e.setFecha(fecha1); 
          e.setLugar(place); 
          e.setCategoria(category); 
          eventos.add(e);                
         }            
        } 
       } 
      }    
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } catch (ParseException e1) { 
      e1.printStackTrace(); 
     } 
     return null;   
    } 

На postExecute я буду обновлять адаптер. Я печатал Журналы и, кажется, иногда, приложение пытается многократно выполнять асинтезу onScroll, не касаясь экрана. Я защитил выполнение asynctask булевым.

Log:

07-22 16:53:06.662: E/AndroidRuntime(391): FATAL EXCEPTION: main 
07-22 16:53:06.662: E/AndroidRuntime(391): java.lang.IllegalStateException: The content of the adapter 
has changed but ListView did not receive a notification. 
Make sure the content of your adapter is not modified 
from a background thread, but only from the UI thread. 
[in ListView(2131099648, class android.widget.ListView) 
with Adapter(class android.widget.HeaderViewListAdapter)] 
07-22 16:53:06.662: E/AndroidRuntime(391): at android.widget.ListView.layoutChildren(ListView.java:1510) 
07-22 16:53:06.662: E/AndroidRuntime(391): at android.widget.AbsListView.onLayout(AbsListView.java:1260) 
07-22 16:53:06.662: E/AndroidRuntime(391): at android.view.View.layout(View.java:7175) 
07-22 16:53:06.662: E/AndroidRuntime(391): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254) 

OnCreate:

public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.all_products); 
new LoadAllProducts().execute(); 
lv = (ListView) findViewById(R.id.lista); 
lv.setOnScrollListener(new OnScrollListener() { 
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
int elementoFinal=firstVisibleItem + visibleItemCount; 
if (inicio<=totalConsultas){ 
    if (elementoFinal==totalItemCount && !primeraEjecucion && !cargando){ 
    new LoadAllProducts().execute(); 
    } 
}else{ 
if (control){ 
    lv.removeFooterView(footerView);      
control=false; 
} 

} 
} 
}); 
} 
+0

опубликовать ваш логарифм – wtsang02

+0

@ wtsang02 – n4h1n

+0

Показать код, выполняемый этой задачей. – wtsang02

ответ

0

Вызов adapter.notifyDataSetChanged() каждый раз, когда вы меняете свои данные.

+0

Я вызываю адаптер на postExecute(), сразу после изменения данных – n4h1n

+0

Исключение указано наоборот. – tbruyelle

+0

Я знаю, иногда я получаю это исключение, в другое время я получаю свое приложение с диалоговым окном «Загрузка» все время без каких-либо исключений – n4h1n

0

Я предполагаю, что eventos - это массив, который вы передали в адаптер, не меняйте его с doInBackground. Вместо этого вы можете настроить AsyncTask для возврата класса Evento, который передаст его в onPostExecute. Оттуда звоните eventos.add(e), вам нужно изменить содержимое адаптера только в основном потоке, где выполняется onPostExecute.

+0

eventos является arraylist моего класса Evento. Я добавляю каждый Evento в массивList, а затем, в postExecute, я создаю свой адаптер класса, передавая ему eventos. Это правильно или я должен делать это, как вы сказали мне? – n4h1n

+0

попробуйте добавить его в onPostExecute. Если два экземпляра этого могут быть запущены, вы могли бы уже передать eventos в адаптер, когда второй пытается его изменить. – adonal3

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