【问题标题】:Error when load more data with event scroll of listview使用列表视图的事件滚动加载更多数据时出错
【发布时间】:2013-04-08 04:43:50
【问题描述】:

列表视图的滚动有问题。我有一个像这样的课程:

private int itemsPerPage = 6;
private int count = 0;
private boolean loadingMore = false;
private ArrayList<Item> item;
private ListItemAdapter adapter;
View footerView;
private JSONArray array;
private String json;

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.menu);
    lvListItem = (ListView) findViewById(R.id.lvListItem);
    item = new ArrayList<Item>();
    footerView = ((LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.list_footer, null, false);

    json = new JSONParse()
                    .getData("....");
    array = new JSONArray(json);

    load();
    adapter = new ListItemAdapter(this, 0, item);
    lvListItem.addFooterView(footerView);
    lvListItem.setAdapter(adapter);

    lvListItem.setOnScrollListener(new OnScrollListener() {

        public void onScrollStateChanged(AbsListView view, int scrollState) {
            // TODO Auto-generated method stub

        }

        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            // TODO Auto-generated method stub
            int lastInScreen = firstVisibleItem + visibleItemCount;

            // is the bottom item visible & not loading more already ? Load
            // more !
            if ((lastInScreen == totalItemCount) && !(loadingMore)) {
                Thread thread = new Thread(null, loadData);
                thread.start();
            }
        }
    });
    }

public void load(){
for (int i = 0; i < itemsPerPage; i++) {
    if (count == array.length()) {
        lvListItem.removeFooterView(footerView);
        break;
    }
    /*****Code to load data*******/
}
}


private Runnable loadData = new Runnable() {
    @Override
    public void run() {

        loadingMore = true;


        item = new ArrayList<Item>();


        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        load();


        runOnUiThread(returnRes);

    }
};


private Runnable returnRes = new Runnable() {
    @Override
    public void run() {


        if (item != null && item.size() > 0) {
            for (int i = 0; i < item.size(); i++)
                adapter.add(item.get(i));
        }


        if (count == array.length())
            lvListItem.removeFooterView(footerView);
        adapter.notifyDataSetChanged();

        // Done loading more.
        loadingMore = false;
    }
};

如果我只是使用 load(),它会运行并且 listview 显示数据正常。但是当我滚动列表视图时,它会抛出错误:

 D/AndroidRuntime(1635): Shutting down VM
  W/dalvikvm(1635): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
   E/AndroidRuntime(1635): FATAL EXCEPTION: main
   E/AndroidRuntime(1635): java.lang.IndexOutOfBoundsException: Invalid index 6, size is 6
   E/AndroidRuntime(1635):  at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
   E/AndroidRuntime(1635):  at java.util.ArrayList.get(ArrayList.java:304)

我需要帮助

【问题讨论】:

  • 这是整个堆栈跟踪吗?
  • 你在 load() 中操作 item 吗?
  • 是的,我在 load() 中为项目添加了价值

标签: java android android-layout android-intent android-emulator


【解决方案1】:

您的数组似乎只有 6 个元素,而您正试图访问索引为 6 的元素,这实际上是第 7 个元素,所以

改变

itemsPerPage = 5;` 

【讨论】:

    【解决方案2】:

    您的代码根本不是线程安全的。您正在从多个线程访问共享数据而没有任何类型的锁定。您的 item 数组可能在您的工作线程中被重新初始化,而它正在从您的 resultRes 可运行(在主线程上运行)中读取,这将导致看似不可能的越界异常。

    创建一个对象以用作您的互斥锁:

    private final Object monitor = new Object(); // an ivar in your Activity
    

    然后在访问共享数据(如itemloadingMore)时,创建一个临界区,例如:

    synchronized(monitor) {
        item = new ArrayList<Item>();
    }
    
    synchronized(monitor) {
        if (item != null && item.size() > 0) {
            for (int i = 0; i < item.size(); i++)
                adapter.add(item.get(i));
        }
    }
    
    synchronized(monitor) {
        if ((lastInScreen == totalItemCount) && !(loadingMore)) {
            Thread thread = new Thread(null, loadData);
            thread.start(); // will exit critical section before new thread execution begins
        }
    }
    

    等等。我将把它作为练习留给你,让你弄清楚应该在哪里完成其余的锁定。

    【讨论】:

    • 当我从数组中获取数据时,它可以工作,但是当我从 web 服务获取数据时,它不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 2014-03-14
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    相关资源
    最近更新 更多