如果在滚动时通知listAdapter并在大约20秒后崩溃而不滚动,则向上或向下滚动列表视图时应用程序崩溃

时间:2015-07-01 17:00:18

标签: android listview

我有一个带有customListadapter的Listview。我使用每6秒运行asynkTask的处理程序用新数据更新arraylist然后我在opP​​ostExcute()上调用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)

1 个答案:

答案 0 :(得分:1)

您可能会收到ConcurrentModificationException,因为您有两个线程访问stocksListdoInBackground正在一个单独的线程上运行,并且正在从适配器读取数据的同时将数据添加到列表中。

解决方案是不共享ArrayList。在doInBackground中,您可能应该创建一个仅包含JSON中新数据的新ArrayList。然后,在onPostExecute(在主线程上调用)中调用stocksList.clear()并添加参数stocksList中的所有内容(您应该将其重命名为result以避免混淆)在致电this.stocksList之前致notifyDataSetChanged()