Error-CursorIndexOutOfBoundsException:请求索引0,大小为0

时间:2016-12-31 06:08:37

标签: android android-viewpager android-sqlite

我的问题:

在我的项目中,我有一个sqlite数据库。我尝试在另一个项目中测试这些相同的类(Database Handler类和helper class-Hitlist.java),执行简单的操作,例如添加到数据库,获取计数,获取数据库中所有行的列表,并且它工作得很好。但是在这个带有viewpager的项目中,每个页面都从数据库中提取数据,当我的视图寻呼机适配器从数据库中请求一行时,会出现此错误。我在StackOverflow上看到了很多关于类似标题的问题,但没有一个能解决我的问题。

logcat:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rohan.hitlistofarya/com.rohan.hitlistofarya.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
                                                                             at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2456)
                                                                             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2539)
                                                                             at android.app.ActivityThread.access$900(ActivityThread.java:159)
                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1384)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                             at android.os.Looper.loop(Looper.java:152)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5507)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                          Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
                                                                             at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
                                                                             at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
                                                                             at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
                                                                             at com.rohan.hitlistofarya.DBHandler.getPerson(DBHandler.java:102)
                                                                             at com.rohan.hitlistofarya.VpagerAdapter.getPageTitle(VpagerAdapter.java:40)
                                                                             at android.support.design.widget.TabLayout.populateFromPagerAdapter(TabLayout.java:903)
                                                                             at android.support.design.widget.TabLayout.setPagerAdapter(TabLayout.java:894)
                                                                             at android.support.design.widget.TabLayout.setupWithViewPager(TabLayout.java:807)
                                                                             at android.support.design.widget.TabLayout.setupWithViewPager(TabLayout.java:768)
                                                                             at android.support.design.widget.TabLayout.setupWithViewPager(TabLayout.java:746)
                                                                             at com.rohan.hitlistofarya.MainFragment.onCreateView(MainFragment.java:48)
                                                                             at android.support.v4.app.Fragment.performCreateView(Fragment.java:2080)
                                                                             at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
                                                                             at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
                                                                             at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
                                                                             at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
                                                                             at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
                                                                             at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:604)
                                                                             at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
                                                                             at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1277)
                                                                             at android.app.Activity.performStart(Activity.java:6321)
                                                                             at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2419)
                                                                             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2539) 
                                                                             at android.app.ActivityThread.access$900(ActivityThread.java:159) 
                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1384) 
                                                                             at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                             at android.os.Looper.loop(Looper.java:152) 
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5507) 
                                                                             at java.lang.reflect.Method.invoke(Native Method) 
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

DBHandler类:

public class DBHandler extends SQLiteOpenHelper {

    private static DBHandler sInstance;

    private static final int DATABASE_VERSION = 1;


    private static final String DATABASE_NAME = "hitlist";


    private static final String TABLE_NAME = "hitlistOfArya";


    private static final String COLUMN_ID = "id";
    private static final String COLUMN_NAME = "name";
    private static final String COLUMN_REASON = "reason";
    private static final String COLUMN_STATUS="dead";
    private static final String COLUMN_FATE="fate";
    private static final String COLUMN_HOUSE="allegiance";
    private static final String COLUMN_EXTRA="extra";
    private static final String COLUMN_IMG="image";

    private DBHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public static synchronized DBHandler getInstance(Context context) {

        if (sInstance == null) {
            sInstance = new DBHandler(context.getApplicationContext());
        }
        return sInstance;
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_NAME + "("
                + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + COLUMN_NAME + " TEXT,"
                + COLUMN_REASON + " TEXT,"
                + COLUMN_STATUS + " INTEGER,"
                + COLUMN_FATE + " TEXT,"
                + COLUMN_HOUSE + " TEXT,"
                + COLUMN_EXTRA + " TEXT,"
                + COLUMN_IMG + " TEXT" + ")";
        db.execSQL(CREATE_CONTACTS_TABLE);
    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);

// Create tables again
        onCreate(db);
    }


    public void addPerson(Hitlist person) {
        SQLiteDatabase db = this.getWritableDatabase();
        int dead=person.isDead()?1:0;

        ContentValues values = new ContentValues();
        values.put(COLUMN_NAME, person.getName());
        values.put(COLUMN_REASON, person.getReason());
        values.put(COLUMN_STATUS,dead);
        values.put(COLUMN_FATE, person.getFate());
        values.put(COLUMN_HOUSE, person.getAllegiance());
        values.put(COLUMN_EXTRA, person.getExtra());
        values.put(COLUMN_IMG, person.getImg());

// Inserting Row
        db.insert(TABLE_NAME, null, values);
        db.close(); // Closing database connection
    }

    Hitlist getPerson(int id) {
        SQLiteDatabase db = this.getReadableDatabase();
        Hitlist person=null;

        Cursor cursor = db.query(
                TABLE_NAME,
                new String[] { COLUMN_ID, COLUMN_NAME, COLUMN_REASON, COLUMN_STATUS, COLUMN_FATE, COLUMN_HOUSE, COLUMN_EXTRA, COLUMN_IMG },
                COLUMN_ID + "=?",
                new String[] { String.valueOf(id) }, null, null, null, null);
        if (cursor != null){
            cursor.moveToFirst();
        //*************************
        boolean dead=(Integer.parseInt(cursor.getString(3))==0)?false:true;//DBHandler line number-102
        person = new Hitlist(Integer.parseInt(cursor.getString(0)),
                cursor.getString(1), cursor.getString(2), dead,
                cursor.getString(4), cursor.getString(5),
                cursor.getString(6), cursor.getString(7));

}
        return person;

    }


    public List<Hitlist> getAllPerssons() {
        List<Hitlist> persons = new ArrayList<Hitlist>();


        String selectQuery = "SELECT * FROM "+TABLE_NAME;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        Hitlist person;

        if (cursor.moveToFirst()) {
            do {
                person = new Hitlist();
                person.setId(Integer.parseInt(cursor.getString(0)));
                person.setName(cursor.getString(1));
                person.setReason(cursor.getString(2));
                boolean dead= (Integer.parseInt(cursor.getString(3))==0)?false:true;
                person.setDead(dead);
                person.setFate(cursor.getString(4));
                person.setAllegiance(cursor.getString(5));
                person.setExtra(cursor.getString(6));
                person.setImg(cursor.getString(7));

                persons.add(person);
            } while (cursor.moveToNext());
        }

        db.close();

        return persons;

    }


    public int editPerson(Hitlist person) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(COLUMN_NAME, person.getName());
        values.put(COLUMN_REASON, person.getReason());
        values.put(COLUMN_STATUS,person.isDead());
        values.put(COLUMN_FATE, person.getFate());
        values.put(COLUMN_HOUSE, person.getAllegiance());
        values.put(COLUMN_EXTRA, person.getExtra());
        values.put(COLUMN_IMG, person.getImg());

// updating row
        return db.update(TABLE_NAME, values, COLUMN_ID + " = ?",
                new String[] { String.valueOf(person.getId()) });

    }

}

VpagerAdapter类:

public class VpagerAdapter extends SmartFragmentStatePagerAdapter {

    private int pages=2;
    private DBHandler myDB;

    public VpagerAdapter(FragmentManager fm, DBHandler myDB){
        super(fm);
        this.myDB=myDB;
    }

    public int getPages() {
        return pages;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }


    @Override
    public Fragment getItem(int position) {
        return fragment1.newInstance(position);
    }

    public void changePages(){pages++;}

    @Override
    public int getCount() {
        return pages;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        //***************************************
        return myDB.getPerson(position).getName();//This line 40 is showing error
    }
}

MainFragment类:

public class MainFragment extends Fragment{

    private ViewPager mPager;

    private VpagerAdapter mAdapter;

    static DBHandler myDB;

    static Hitlist person=new Hitlist();

    TabLayout myTabs;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myDB=DBHandler.getInstance(getActivity());
        if(myDB.getPersonsCount()==0){
            person=new Hitlist("Shruti","XYZ",false,null,null,null,"@drawable/arya");
            myDB.addPerson(person);
            person=new Hitlist("Rohan","TUV",false,null,null,null,"@drawable/arya2");
            myDB.addPerson(person);
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.main_fragment,container,false);
        mPager= (ViewPager) view.findViewById(R.id.ViewPager);
        mPager.setPageTransformer(true,new CubeOutTransformer());
        mAdapter=new VpagerAdapter(getActivity().getSupportFragmentManager(),myDB);
        mPager.setAdapter(mAdapter);
        myTabs= (TabLayout) view.findViewById(R.id.my_tabs);
        //********************************
        myTabs.setupWithViewPager(mPager);//MainFragment line no.48


        return view;
    }
}

我已经通过旁边的注释指定了哪些行在课堂上显示错误。

我已在 MainActivity.java 中初始化了我的DBHandler实例,并建议this page

//In MainActivity.java, onCreate method()
myDB=DBHandler.getInstance(this);

修改 -

我刚才注意到,如果我在MainActivity中调用myDB.getPerson(int id),它可以正常工作。然后同样的错误来自于在fragment1中调用getPerson()(提供给viewpager的片段)。当我在MainActivity中调用getPerson()时,我还将数据添加到MainActivity的onCreate

为什么会这样?数据库实例应该在任何地方都相同。是什么改变了让应用程序崩溃?

修改#2 - 我还尝试在MainFragment类中调用getPerson(),它仍然没有显示光标超出范围的错误。我不知道为什么会发生这种情况.. MainFragment中的getPerson()显然在myTabs.setupWithViewPager(mPager)行之前被调用

欢迎所有建议。谢谢!

解 -

问题出在viewpager的getPageTitle()方法中。我将位置传递给方法getPerson(),该方法采用整数&#34; ID&#34;作为参数。 ID被索引为1而位置被索引为0.只需传递&#34;位置+ 1&#34;而不是&#34;位置&#34; 到getPageTitle()的方法调用解决了我的问题。所以,我的光标不是null它是空的,getPerson()中的查询没有失败,只是查询中没有行,我试图访问它。

2 个答案:

答案 0 :(得分:1)

如果从Fragment初始化DBHandler,请使用

myDB=DBHandler.getInstance(getActivity());  

getPerson(int id)方法中使用如下

 if (cursor != null) {
   if (cursor.moveToFirst()) {
     boolean dead=(Integer.parseInt(cursor.getString(3))==0)?false:true; 
     Hitlist person = new Hitlist(Integer.parseInt(cursor.getString(0)),
            cursor.getString(1), cursor.getString(2), dead,
            cursor.getString(4), cursor.getString(5),
            cursor.getString(6), cursor.getString(7));

    return person;
        }
    }

希望它能奏效。

答案 1 :(得分:1)

<强> android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0

这意味着, Cursor 要么 null ,要么为空0 rows 。

Hitlist getPerson(int id) {
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.query(
            TABLE_NAME,
            new String[] { COLUMN_ID, COLUMN_NAME, COLUMN_REASON, COLUMN_STATUS, 
            COLUMN_FATE, COLUMN_HOUSE, COLUMN_EXTRA, COLUMN_IMG },
            COLUMN_ID + "=?",
            new String[] { String.valueOf(id) }, null, null, null, null);

    //Edit Part
    if (cursor != null && cursor.getCount()>0) {//perform operations on cursor only when 
                                              //it is neither Null nor empty
            //another thing, you should check if moveToFirst() returns something or not
            Hitlist person;
            if (cursor.moveToFirst()) { //now here fetch things from cursor
                    boolean dead=(Integer.parseInt(cursor.getString(3))==0)?false:true;
                    person = new Hitlist(Integer.parseInt(cursor.getString(0)),
                    cursor.getString(1), cursor.getString(2), dead,
                    cursor.getString(4), cursor.getString(5),
                    cursor.getString(6), cursor.getString(7));

                    cursor.close();
                    return person;
            } else { 
                    cursor.close();
                    //print some message via Snackbar or Toast
            }

     } else { throw new Exception(); }

    cursor.close();
    throw new Exception();
}