0

2 つの ayntask インスタンスを実行しています。1 つは onCreate で、もう 1 つは onScroll ハンドラで実行しています。このアプリの意図は、Web サービス X の情報量を介してダウンロードし、スクロールが一番下まで来ると、情報をロードし続けることです。情報は十分に読み込まれますが、読み込みが続き、アプリがクラッシュすることがあります。

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 で、アダプターを更新しています。ログを印刷しましたが、アプリが画面に触れずに asynctask onScroll を何度も実行しようとすることがあるようです。asynctask の実行をブール値で保護しました。

ログ:

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)

作成時:

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

}
}
});
}
4

2 に答える 2

0

アダプターに渡した配列だと思います。doInBackgroundeventosから変更しないでください。代わりに、AsyncTask を設定してクラス Eventto を返すことができます。これにより、それが onPostExecute に渡されます。そこから calleventos.add(e)を呼び出して、onPostExecute が実行されるメイン スレッドでのみアダプタの内容を変更する必要があります。

于 2013-07-22T17:30:06.670 に答える
0

adapter.notifyDataSetChanged()データを変更するたびに呼び出します。

于 2013-07-22T17:18:39.163 に答える