光标outofbounds异常 - Android

时间:2013-09-14 11:40:31

标签: android android-listview android-sqlite android-cursoradapter

我有一个包含6列的数据库,我使用simplecursor适配器在列表视图中填充它们。在我不滚动列表视图之前,一切似乎都很好。如果我向下滚动并再次向上,我会出现光标异常(仅当我向上滚动时)。我的代码如下:

我的活动课程:

    mySQLiteAdapter.open();

    String[] arrayColumns = new String[] { Dbhelper.KEY_PKG,
            Dbhelper.KEY_APP,Dbhelper.KEY_ICON, Dbhelper.KEY_STAT };
    int[] arrayViewIDs = new int[] { R.id.pkgname, R.id.appname, R.id.app_icon, R.id.allow_mode };

    cursor = mySQLiteAdapter.getAllFolders();

    adapter = new SimpleCursorAdapter(
            getActivity(), R.layout.listview_items,
            cursor, arrayColumns, arrayViewIDs);
    lv.setAdapter(adapter);
    mySQLiteAdapter.close();

adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
            @Override
            public boolean setViewValue (View view, Cursor cursor, int columnIndex){
                if (view.getId() == R.id.app_icon) {
                    ImageView IV1=(ImageView) view;
                    Bitmap icon;
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                    byte[] image = null;
                    cursor.moveToFirst();     
                    image = mySQLiteAdapter.getIcon(c);            
                    icon = BitmapFactory.decodeByteArray(image , 0, image .length, options);
                    IV1.setImageBitmap(icon);


                    if (view.getId() == R.id.allow_mode) {
                        ImageView IV2=(ImageView) view;
                        int stat_icon;
                        stat_icon = mySQLiteAdapter.getStat(c);
                        IV2.setImageResource(stat_icon);

                    }
                    c++;
                    return true;
            }
            return false;
}
我的dbhelper类中的

getIcon()和getStat()方法:

public byte[] getIcon(int row){
    byte[] byteArray = {};
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.query(TABLE_NAME, new String[] {  
            KEY_ICON}, KEY_ID+"=="+"'"+row+"'", null, null, null, null);    

    cursor.moveToNext();
    byteArray = cursor.getBlob(0);
     cursor.close();

     return byteArray;

}
public int getStat(int row){
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(TABLE_NAME, new String[] {  
            KEY_STAT}, KEY_ID+"=="+"'"+row+"'", null, null, null, null);
    cursor.moveToNext();
    int ic = cursor.getInt(0);
    return ic;
}

我的logcat是:

09-14 11:16:06.444: E/AndroidRuntime(3638): FATAL EXCEPTION: main
09-14 11:16:06.444: E/AndroidRuntime(3638): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:424)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:44)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at com.vijai.selinuxcontroller.Dbhelper.getIcon(Dbhelper.java:143)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at com.vijai.selinuxcontroller.Apps$3.setViewValue(Apps.java:119)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:146)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.CursorAdapter.getView(CursorAdapter.java:250)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.AbsListView.obtainView(AbsListView.java:2143)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.ListView.makeAndAddView(ListView.java:1831)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.ListView.fillUp(ListView.java:708)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.ListView.correctTooHigh(ListView.java:1397)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.ListView.fillGap(ListView.java:639)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4930)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3087)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:3361)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.View.dispatchTouchEvent(View.java:7246)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.app.Activity.dispatchTouchEvent(Activity.java:2410)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.View.dispatchPointerEvent(View.java:7426)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:171)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4342)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4382)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.Choreographer.doCallbacks(Choreographer.java:562)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.Choreographer.doFrame(Choreographer.java:530)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.os.Handler.handleCallback(Handler.java:725)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.os.Looper.loop(Looper.java:137)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at android.app.ActivityThread.main(ActivityThread.java:5041)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at java.lang.reflect.Method.invokeNative(Native Method)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at java.lang.reflect.Method.invoke(Method.java:511)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-14 11:16:06.444: E/AndroidRuntime(3638):     at dalvik.system.NativeStart.main(Native Method)
09-14 11:16:14.304: E/Trace(3680): error opening trace file: No such file or directory (2)

logcat中提到的第143行是:

byteArray = cursor.getBlob(0);

在getIcon()方法中。我现在如何解决错误?谢谢你的时间。

1 个答案:

答案 0 :(得分:0)

您没有检查cursor.getCount()>0
如果没有找到结果 cursor.getCount()= -1;
所以它会通过这个例外 你还要验证 cursor!= null

if (view.getId() == R.id.app_icon && cursor != null && cursor.getCount() > 0) {
                    ImageView IV1=(ImageView) view;
                    Bitmap icon;
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                    byte[] image = null;
                    cursor.moveToFirst();     
                    image = mySQLiteAdapter.getIcon(c);            
                    icon = BitmapFactory.decodeByteArray(image , 0, image .length, options);
                    IV1.setImageBitmap(icon);


                    if (view.getId() == R.id.allow_mode) {
                        ImageView IV2=(ImageView) view;
                        int stat_icon;
                        stat_icon = mySQLiteAdapter.getStat(c);
                        IV2.setImageResource(stat_icon);

                    }
                    c++;
                    return true;
            }