我有一个带有customListadapter的Listview。我使用每6秒运行asynkTask的处理程序用新数据更新arraylist然后我在opPostExcute()上调用notifyDataSetChanged()。数据显示在listView中并更新,一切正常。但是,如果我向上或向下滚动listView,应用程序崩溃。
这些是全局变量:
ListView lv1;
SwipeRefreshLayout mSwipeRefreshLayout;
PostTask postTask = new PostTask();
StockQuoteListAdapter stockQuoteListAdapter;
ArrayList<StockQuote> stocksList=new ArrayList<StockQuote>();
这是onCreate上的活动:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
result = inflater.inflate(R.layout.indeces_fragment,container,false);
mSwipeRefreshLayout = (SwipeRefreshLayout) result.findViewById(R.id.activity_main_swipe_refresh_layout);
lv1 = (ListView) result.findViewById(R.id.stocks_list);
stockQuoteListAdapter = new StockQuoteListAdapter(result.getContext(), stocksList);
lv1.setAdapter(stockQuoteListAdapter);
mSwipeRefreshLayout.setColorSchemeResources(R.color.orange, R.color.green, R.color.blue);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//mSwipeRefreshLayout.setRefreshing(false);
}
});
useHandler();
return result;
}
这是Handler每6秒运行一次AsyncTask:
Handler mHandler;
public void useHandler() {
mHandler = new Handler();
mHandler.postDelayed(mRunnable, 2000);
}
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
try
{
new PostTask().execute();
mHandler.postDelayed(mRunnable, 6000);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
};
这是AsyncTask:
private class PostTask extends AsyncTask<Void, Void, ArrayList<StockQuote>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<StockQuote> doInBackground(Void... params) {
stocksList.clear();
....some json parsing here
return stocksList;
}
}catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(ArrayList<StockQuote> stocksList) {
super.onPostExecute(stocksList);
stockQuoteListAdapter.notifyDataSetChanged();
}
我做错了,因为我是新手。
错误:
on: Invalid index 8, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at profestock.moe.org.swipewithtabs.Stocks.StockQuoteListAdapter.getView(StockQuoteListAdapter.java:58)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
at android.widget.ListView.fillGap(ListView.java:662)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4991)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3418)
at android.widget.AbsListView.onTouchMove(AbsListView.java:3801)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3632)
at android.view.View.dispatchTouchEvent(View.java:8471)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
答案 0 :(得分:1)
您可能会收到ConcurrentModificationException,因为您有两个线程访问stocksList
。 doInBackground
正在一个单独的线程上运行,并且正在从适配器读取数据的同时将数据添加到列表中。
解决方案是不共享ArrayList。在doInBackground
中,您可能应该创建一个仅包含JSON中新数据的新ArrayList。然后,在onPostExecute
(在主线程上调用)中调用stocksList.clear()
并添加参数stocksList
中的所有内容(您应该将其重命名为result
以避免混淆)在致电this.stocksList
之前致notifyDataSetChanged()
。