0

我正在执行两个 asyntask 实例,其中一个在 onCreate 中,另一个在 onScroll 处理程序中。该应用程序的目的是通过网络服务下载 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。我用布尔值保护了异步任务的执行。

日志:

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

我猜eventos是您传递给适配器的数组,不要从 doInBackground 更改它。相反,您可以将 AsyncTask 设置为返回 Evento 类,该类会将其传递给 onPostExecute。从那里调用eventos.add(e),您只需要在主线程上更改适配器的内容,这是运行 onPostExecute 的地方。

于 2013-07-22T17:30:06.670 回答
0

adapter.notifyDataSetChanged()每次更改其数据时调用。

于 2013-07-22T17:18:39.163 回答