2016-12-31 67 views
0

我的問題:錯誤-CursorIndexOutOfBoundsException:指數0請求,大小0

在我的項目我有一個SQLite數據庫。我嘗試在另一個項目中測試這些相同的類(數據庫處理程序類和助手類--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; 
    } 
} 

我已指定哪些線被示出由在它旁邊註釋在類的誤差。

我已經初始化了我的DBHandler實例MainActivity.javathis page建議。

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

編輯 -

我只注意到,如果我在MainActivity調用myDB.getPerson(INT ID),它工作正常。然後同樣的錯誤出現由於getPerson()被稱爲片段1。當我在MainActivity叫getPerson()(這是提供給viewpager片段),我也動了另外的數據到數據庫MainActivity的onCreate

爲什麼這是否發生?數據庫實例在任何地方都應該相同。什麼改變,使應用程序崩潰?

編輯#2 我也試圖調用getPerson()在MainFragment類,它仍然沒有顯示光標的錯誤出界。我不知道爲什麼會出現這種情況.. 的getPerson()在MainFragment的myTabs.setupWithViewPager(mPager)線

所有建議,歡迎前明顯調用。謝謝!

溶液 -

的問題是在getPageTitle viewpager的()方法。我將位置傳遞給方法getPerson(),該方法以整數「ID」作爲參數。 ID索引爲1,而位置索引爲0.只需將「position + 1」而不是「position」 傳遞給getPageTitle()的方法調用即可解決我的問題。所以,我的遊標不是空的,它是空的,getPerson()中的查詢沒有失敗,只是查詢中沒有行,我試圖訪問它。

+0

在您的數據庫處理程序中,如果(cursor!= null)cursor.moveToFirs();如果條件結束....如果(遊標!= null){cursor.moveToFirs();這裏移動你的代碼來從光標中提取東西} 你的光標將是空的,它是查詢空/空遊標 –

+0

沒有運氣,錯誤是一樣的。 –

+0

你的瀏覽器適配器類和db類是在同一個包中? –

回答

1

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

這意味着,Cursor要麼或它是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(); 
} 
+0

這就是問題..遊標是空的,因爲我已經把條件檢查爲空。我不應該得到這樣的空遊標,因爲我的數據庫中有數據,我試圖從VpagerAdapter訪問它。如果我嘗試從MainFragment訪問我的數據庫,它不會給出錯誤。這意味着在我的適配器的getPageTitle方法中,position的值不能是1或2 ...爲什麼? –

+0

請確保您的數據庫中有數據? –

+0

我知道了,位置是0索引,而id是1索引。 –

1

如果從片段初始化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; 
     } 
    } 

希望它會工作。

相關問題