Android 在sqlite数据库的recyclerview中设置数据时发生IndexAutofBound异常
我从sqlite获取数据并将其填充到recyclerview中,但在填充数据的同时,我在我的logcat中获得IndexOutOfBoundException。 有人能告诉我为什么我会得到这个例外吗 Databasehelper类代码:Android 在sqlite数据库的recyclerview中设置数据时发生IndexAutofBound异常,android,xml,android-fragments,android-recyclerview,android-sqlite,Android,Xml,Android Fragments,Android Recyclerview,Android Sqlite,我从sqlite获取数据并将其填充到recyclerview中,但在填充数据的同时,我在我的logcat中获得IndexOutOfBoundException。 有人能告诉我为什么我会得到这个例外吗 Databasehelper类代码: public class DatabaseHelper extends SQLiteOpenHelper { public static final String DATABASE_NAME = "history.db"; public static fina
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "history.db";
public static final String TABLE_NAME = "history_table";
public static final String COL_1 = "ID";
public static final String COL_2 = "URL";
public static final String COL_3 = "TITLE";
public DatabaseHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, 1);
SQLiteDatabase db = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+ TABLE_NAME+"(ID INTEGER PRIMARY KEY AUTOINCREMENT, URL TEXT, TITLE TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean insertData(String url, String title){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_2, url);
contentValues.put(COL_3, title);
long result = db.insert(TABLE_NAME,null,contentValues);
if(result == -1) {
return false;
}
else{
return true;
}
}
public boolean updateData(String id, String url, String title) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValue= new ContentValues();
contentValue.put(COL_1, id);
contentValue.put(COL_2, url);
contentValue.put(COL_3, title);
db.update(TABLE_NAME, contentValue, "ID= ?",new String[]{id} );
return true;
}
public Cursor getalldata() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from "+ TABLE_NAME, null);
return res;
}
public Cursor getuniquedata(String id){
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from "+ TABLE_NAME+" where " +COL_2+" = ?", new String []{id});
return res;
}
public void deletedata(String id){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, COL_2+ "= ?", new String []{id});
}
}
在模型中填充数据并设置适配器时的代码:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_history, container, false);
button = (Button) view.findViewById(R.id.button1);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview8);
historyModels = new ArrayList<>();
LinearLayoutManager mainlayout= new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(mainlayout);
recyclerView.setItemAnimator(new DefaultItemAnimator());
mydb = new DatabaseHelper(getContext());
Cursor res = mydb.getalldata();
res.moveToFirst();
if(res!=null) {
while (res.moveToNext()) ;
{
HistoryModel historyModel = new HistoryModel(res.getString(1), res.getString(2)); //this line is giving error
historyModels.add(historyModel);
}
mydb.close();
historyRecyclerAdapter = new HistoryRecyclerAdapter(historyModels, getContext());
recyclerView.setAdapter(historyRecyclerAdapter);
}
return view;
}
日志错误:
android.database.CursorIndexOutOfBoundsException: Index 8 requested, with a size of 8
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.example.haryanvigaane.Fragment.HistoryFragment.onCreateView(HistoryFragment.java:77)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
首先是这一行:
res.moveToFirst();
将光标的索引移动到第一行
然后开始一个空循环:
while (res.moveToNext());
因为末尾有分号,即使您删除了它,您创建的列表也会错过第一行。
在这个空循环之后,它只推进光标的索引,并最终在光标的最后一行之后设置,在花括号内的以下代码块中(这不是while
)尝试检索两列的值,这就是引发错误的地方,因为光标的索引所在的位置没有行。
将代码更改为:
Cursor res = mydb.getalldata();
while (res.moveToNext()) {
HistoryModel historyModel = new HistoryModel(res.getString(1), res.getString(2));
historyModels.add(historyModel);
}
res.close();
mydb.close();
historyRecyclerAdapter = new HistoryRecyclerAdapter(historyModels, getContext());
recyclerView.setAdapter(historyRecyclerAdapter);
请注意,使用getColumnIndex()
而不是显式设置列的索引是一种很好的做法,因此我建议:
HistoryModel historyModel = new HistoryModel(
res.getString(res.getColumnIndex(DatabaseHelper.URL)),
res.getString(res.getColumnIndex(DatabaseHelper.TITLE))
);
我猜它是在迭代最后一个元素时出现的,所以只需更改while to-do{//your logic}while(res.moveToNext());伟大的它工作正常,所有数据都正常。非常感谢您,是的,我会记得在以后的项目中使用getColumnIndex()。
HistoryModel historyModel = new HistoryModel(
res.getString(res.getColumnIndex(DatabaseHelper.URL)),
res.getString(res.getColumnIndex(DatabaseHelper.TITLE))
);