我的問題:錯誤-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.java如this 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()中的查詢沒有失敗,只是查詢中沒有行,我試圖訪問它。
在您的數據庫處理程序中,如果(cursor!= null)cursor.moveToFirs();如果條件結束....如果(遊標!= null){cursor.moveToFirs();這裏移動你的代碼來從光標中提取東西} 你的光標將是空的,它是查詢空/空遊標 –
沒有運氣,錯誤是一樣的。 –
你的瀏覽器適配器類和db類是在同一個包中? –