操作ArrayAdapter时的ArrayIndexOutOfBoundsException

时间:2016-04-27 05:59:29

标签: java android listview adapter

长话短说:我有一个带有customAdapter的listView(名为MathAdapter)。此适配器处理CalculationModel类型的ArrayList。默认情况下,我的列表中有~15个CalculationModel,但是,在特殊条件下,我必须删除其中的6个。

由于我是Android开发的新手(我来自iOS),我的第一个基本问题是:

人们通常会在哪里操纵ListData?在我的例子中,片段初始化适配器并传递我的数据列表。在我的应用程序的生命周期中,我操纵此列表并调用notifiyDataSetChanged。一切都按预期工作,我可以一次删除或添加1个CalculationModel而没有任何问题。

删除6个CalculationModels时也没有问题,也可以正常工作。当我尝试使用以下ErrorLog重新插​​入它时,应用程序崩溃:

04-27 07:48:59.194 1766-1766/com.example.test E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.example.test, PID: 1766
   java.lang.ArrayIndexOutOfBoundsException: length=11; index=11
       at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:8271)
       at android.widget.ListView.layoutChildren(ListView.java:1600)
       at android.widget.AbsListView.onLayout(AbsListView.java:2528)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
       at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
       at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
       at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
       at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
       at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
       at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at com.example.test.TouchDisableView.onLayout(TouchDisableView.java:57)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
       at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
       at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
       at android.view.View.layout(View.java:15655)
       at android.view.ViewGroup.layout(ViewGroup.java:4856)
       at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2284)
       at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2004)
       at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1236)
       at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6471)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
       at android.view.Choreographer.doCallbacks(Choreographer.java:603)
       at android.view.Choreographer.doFrame(Choreographer.java:573)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
       at android.os.Handler.handleCallback(Handler.java:733)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:157)
       at android.app.ActivityThread.main(ActivityThread.java:5356)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
       at dalvik.system.NativeStart.main(Native Method)

为了说清楚,我不是Java的新手,我看到ArrayIndexOutOfBounds是问题所在,但我不知道发生这种情况,因为我的列表和适配器中的项目数高于11(14如预期)

代码:

    List<CalculationModel> data;
    List<CalculationModel> backupData = new ArrayList<>();    

@Override
public void onResume() {
    if (mathApp.isCleanPhase) {
        removeNonClearData();
    } else {
        addNonClearData();
    }

    adapter.notifyDataSetChanged();

    super.onResume();
}


    public void removeNonClearData() {
    if (backupData.size() > 0) return;

    for (int i = 0; i < data.size(); i++) {
        CalculationModel tmp = data.get(i);

        String sName = tmp.getSName();

        if (sName.equals("r") || sName.equals("wv") || sName.equals("qv") || sName.equals("tw") || sName.equals("ti") || sName.equals("h") || sName.equals("rs")) {
            backupData.add(data.remove(i));
            i--;
        }
    }

    adapter.itemCount = data.size();
}

public void addNonClearData() {
    if (backupData.size() == 0) return;

    for (int i = 0; i < backupData.size(); i++) {
        //'r' is a default parameter, which shall be in row 6
        if (backupData.get(i).getSName().equals("r")) data.add(5, backupData.remove(i));
        else data.add(backupData.remove(i));
    }

    adapter.itemCount = data.size();

    print(data.size());
}
编辑:忘记提及,数据基本上按照我想要的方式加载,但是当我在列表中再次滚动时,应用程序崩溃了。所有数据都在我希望在那里看到的列表中,但是当向上滚动时, - &gt;崩溃。

如上所述,我只是不明白此错误的来源,因为日志中没有提供有关它的信息......

2 个答案:

答案 0 :(得分:1)

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    private let _queue = NSOperationQueue()

    func applicationDidFinishLaunching(aNotification: NSNotification) {

        _queue.maxConcurrentOperationCount = 1

        _queue.addOperation(Operation())
        _queue.addOperation(Operation())
        _queue.addOperation(Operation())
    }
}

private class Operation: NSOperation {

    override func main() {
        autoreleasepool {
            let count = 100000000
            let p = UnsafeMutablePointer<Int>.alloc(count)
            for i in 0..<count {
                p.advancedBy(i).initialize(i)
            }
            p.destroy(count)
            p.dealloc(count)
        }
    }
}

答案 1 :(得分:1)

经过很长一段时间(基本上是最后2天)的挫折和困惑,我终于明白了这个ListViews的适配器是如何工作的(至少我希望如此)。

如问题中所述,我有以下设置: 一个包含数据列表的片段,以及在初始化时获取此数据列表的适配器。

现在,在处理数据时,适配器有两种不同的行为。

如果只编辑列表中的一个对象(例如,我想在位置4上更改我的CalculationModel的参数“value”,一切正常,并且通过notifyDataSetChanged()接受更改。

如果从列表中删除一个完整的对象,notifyDataSetChanged()也在工作并执行预期的工作。

但是,如果要将一个新对象添加到列表中(或者在我的情况下,重新插入已删除的对象),则必须重新创建整个适配器,因为notifyDataSetChanged()不再有效。< / p>

感谢您的帮助,如果没有评论中的输入,我可能没有这样做。