大家好,我遇到了一些困难,希望你们中的一个可以提供帮助。我正在尝试创建一个小程序来存储我的大学时间表。我在使用SQlite数据库时遇到了一些问题,但这让我很难过。
当我第一次运行该程序时,它强制关闭
我在logcat中得到这个错误
引起:android.database CursorIndexOutOfBoundsException:请求索引0。大小为0
当我再次打开应用程序时,表格已创建,应用程序正常工作。
我不知道为什么第一次没有创建表。
这是代码。
public class Monday extends ListActivity {
int pos = 0, timeInt, count;
String[] times = {"0900-1030","1040-1220","Lunch 1220-1325","1325-1455", "1500-1630"};
String[][] content;
String dayString = "Monday", timeString;
EditText EditTextLesson, EditTextLocation, EditTextTutor, EditTextNotes;
Button btnSave, btnCancel , btnDelete;
Dialog edit;
Intent zoom , mapweb;
Cursor all, getRow;
MonDBAdapter mon;
DBAdapter db;
ListView lv;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.timetablelistview);
content= new String [10][10];
edit = new Dialog(Monday.this);
lv = (ListView) findViewById(android.R.id.list);
lv.addFooterView(buildFooter());
zoom =new Intent(this,Zoom.class);
mapweb =new Intent(this,MapWebView.class);
db = new DBAdapter(this);
db.open();
mon = new MonDBAdapter(this);
mon.open();
all = mon.getAllEntries();
count = all.getCount();
if(count < 4){
for(int i = 0; i < 5; i++){
mon.createEntry("", "", "", "");
}
}
addSections();
}
public void onListItemClick(ListView parent, View v, int position, long id){
switch(position){
case 1:
timeInt= 1;
timeString=("0900-1030");
break;
case 3:
timeInt= 2;
timeString=("1040-1220");
break;
case 5:
timeInt= 3;
timeString=("1220-1325");
break;
case 7:
timeInt= 4;
timeString=("1325-1455");
break;
case 9:
timeInt= 5;
timeString=("1500-1630");
break;
}
editDialog();
}
SectionedAdapter adapter=new SectionedAdapter() {
protected View getHeaderView(String caption, int index,
View convertView,
ViewGroup parent) {
TextView result=(TextView)convertView;
if (convertView==null) {
result=(TextView)getLayoutInflater().inflate(R.layout.header,
null);
}
result.setText(caption);
return(result);
}
};
public void addSections(){
all.moveToFirst();
for(int i = 0; i < 5; i++){
getSectionContent(
times[i],
all.getString(1),
all.getString(2),
all.getString(3),
all.getString(4));
all.moveToNext();
}
}
public void getSectionContent(String time,String lesson,String location,String tutor,String notes){
//adapter to add content to each section
String[] from = new String[] {"lesson", "location", "tutor", "notes"};
int[] to = new int[] {R.id.textViewLesson, R.id.textViewLocation, R.id.textViewTutor, R.id.textViewNotes };
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
map.put("lesson", lesson );
map.put("location", location );
map.put("tutor", tutor );
map.put("notes", notes );
fillMaps.add(map);
SimpleAdapter adapter1 = new SimpleAdapter(this, fillMaps, R.layout.list_view_item, from, to);
adapter.addSection(time,adapter1);
lv.setAdapter(adapter);
}
public void editDialog(){
getRow = mon.getEntry(timeInt);
edit.setTitle("Edit "+ dayString + " " + timeString);
edit.setContentView(R.layout.edit);
edit.setCancelable(true);
btnSave = (Button)edit.findViewById(R.id.btnSave);
btnCancel = (Button)edit.findViewById(R.id.btnCancel);
btnDelete = (Button)edit.findViewById(R.id.btnDelete);
EditTextLesson=(EditText)edit.findViewById(R.id.editTextLesson);
EditTextLocation=(EditText)edit.findViewById(R.id.editTextLocation);
EditTextTutor=(EditText)edit.findViewById(R.id.editTextTutor);
EditTextNotes=(EditText)edit.findViewById(R.id.editTextNotes);
EditTextLesson.setText(getRow.getString(1));
EditTextLocation.setText(getRow.getString(2));
EditTextTutor.setText(getRow.getString(3));
EditTextNotes.setText(getRow.getString(4));
btnCancel.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
edit.cancel();
}
});
btnSave.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//starts at 1 as 0 contain the section time
mon.updateEntry(timeInt,EditTextLesson.getText().toString(),EditTextLocation.getText().toString(), EditTextTutor.getText().toString(),EditTextNotes.getText().toString());
all.requery();
adapter.sections.clear();
addSections();
edit.cancel();
}
});
btnDelete.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
EditTextLesson.setText("");
EditTextLocation.setText("");
EditTextTutor.setText("");
EditTextNotes.setText("");
}
});
edit.show();
}
private View buildFooter() {
Button btn=new Button(this);
btn.setText("Campus map");
btn.setTextSize(18);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(VERSION.SDK.equals("4")||VERSION.SDK.equals("3")||VERSION.SDK.equals("2")||VERSION.SDK.equals("1")){
startActivity(zoom);
}else{
startActivity(mapweb);
}
}
});
return(btn);
}
}
public class DBAdapter {
public static final String DATABASE_NAME = "timetable";
public static final int DATABASE_VERSION = 1;
private static final String MONDAY =
"create table monday (_id integer primary key autoincrement, "
+ MonDBAdapter.LESSON+ " TEXT,"
+ MonDBAdapter.LOCATION+ " TEXT,"
+ MonDBAdapter.TUTOR+ " TEXT,"
+ MonDBAdapter.NOTES+ " TEXT" + ");";
private static final String TUESDAY =
"create table tuesday (_id integer primary key autoincrement, "
+ MonDBAdapter.LESSON+ " TEXT,"
+ MonDBAdapter.LOCATION+ " TEXT,"
+ MonDBAdapter.TUTOR+ " TEXT,"
+ MonDBAdapter.NOTES+ " TEXT" + ");";
private static final String WEDNESDAY =
"create table wednesday (_id integer primary key autoincrement, "
+ MonDBAdapter.LESSON+ " TEXT,"
+ MonDBAdapter.LOCATION+ " TEXT,"
+ MonDBAdapter.TUTOR+ " TEXT,"
+ MonDBAdapter.NOTES+ " TEXT" + ");";
private static final String THURSDAY =
"create table thursday (_id integer primary key autoincrement, "
+ MonDBAdapter.LESSON+ " TEXT,"
+ MonDBAdapter.LOCATION+ " TEXT,"
+ MonDBAdapter.TUTOR+ " TEXT,"
+ MonDBAdapter.NOTES+ " TEXT" + ");";
private static final String FRIDAY =
"create table friday (_id integer primary key autoincrement, "
+ MonDBAdapter.LESSON+ " TEXT,"
+ MonDBAdapter.LOCATION+ " TEXT,"
+ MonDBAdapter.TUTOR+ " TEXT,"
+ MonDBAdapter.NOTES+ " TEXT" + ");";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
this.DBHelper = new DatabaseHelper(this.context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(MONDAY);
db.execSQL(TUESDAY);
db.execSQL(WEDNESDAY);
db.execSQL(THURSDAY);
db.execSQL(FRIDAY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
}
}
public DBAdapter open() throws SQLException
{
this.db = this.DBHelper.getWritableDatabase();
return this;
}
public void close()
{
this.DBHelper.close();
}
}
public class MonDBAdapter {
public static final String ROW_ID = "_id";
public static final String LESSON = "name";
public static final String LOCATION = "model";
public static final String TUTOR = "year";
public static final String NOTES = "notes";
private static final String MONDAY= "monday";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DBAdapter.DATABASE_NAME, null, DBAdapter.DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
public MonDBAdapter(Context ctx) {
this.mCtx = ctx;
}
public MonDBAdapter open() throws SQLException {
this.mDbHelper = new DatabaseHelper(this.mCtx);
this.mDb = this.mDbHelper.getWritableDatabase();
return this;
}
public void close() {
this.mDbHelper.close();
}
public long createEntry(String lesson, String location, String tutor , String notes){
ContentValues initialValues = new ContentValues();
initialValues.put(LESSON, lesson);
initialValues.put(LOCATION, location);
initialValues.put(TUTOR, tutor);
initialValues.put(NOTES, notes);
return this.mDb.insert(MONDAY, null, initialValues);
}
public boolean deleteEntry(long rowId) {
return this.mDb.delete(MONDAY, ROW_ID + "=" + rowId, null) > 0; //$NON-NLS-1$
}
public Cursor getAllEntries() {
return this.mDb.query(MONDAY, new String[] { ROW_ID,
LESSON, LOCATION, TUTOR, NOTES }, null, null, null, null, null);
}
public Cursor getEntry(long rowId) throws SQLException {
Cursor mCursor =
this.mDb.query(true, MONDAY, new String[] { ROW_ID, LESSON,
LOCATION, TUTOR, NOTES}, ROW_ID + "=" + rowId, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public boolean updateEntry(long rowId, String lesson, String location,
String tutor, String notes){
ContentValues args = new ContentValues();
args.put(LESSON, lesson);
args.put(LOCATION, location);
args.put(TUTOR, tutor);
args.put(NOTES, notes);
return this.mDb.update(MONDAY, args, ROW_ID + "=" + rowId, null) >0;
}
这是我在logcat中获得的内容:
ERROR/AndroidRuntime(2464): FATAL EXCEPTION: main
ERROR/AndroidRuntime(2464): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.scotty65/com.scotty65.TabBarExample}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.scotty65/com.scotty65.Monday}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
ERROR/AndroidRuntime(2464): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768)
ERROR/AndroidRuntime(2464): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
ERROR/AndroidRuntime(2464): at android.app.ActivityThread.access$1500(ActivityThread.java:123)
ERROR/AndroidRuntime(2464): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
ERROR/AndroidRuntime(2464): at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(2464): at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(2464): at android.app.ActivityThread.main(ActivityThread.java:3835)
ERROR/AndroidRuntime(2464): at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(2464): at java.lang.reflect.Method.invoke(Method.java:507)
ERROR/AndroidRuntime(2464): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
ERROR/AndroidRuntime(2464): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
/AndroidRuntime(2464): at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(2464): Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.scotty65/com.scotty65.Monday}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
ERROR/AndroidRuntime(2464): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768)
ERROR/AndroidRuntime(2464): at android.app.ActivityThread.startActivityNow(ActivityThread.java:1598)
ERROR/AndroidRuntime(2464): at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
ERROR/AndroidRuntime(2464): at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
答案 0 :(得分:0)
在完成数据库后,我没有看到您实际调用“close()”函数关闭数据库的位置。完成添加部分后,可能会尝试关闭它。我看到你已经提供了关闭它的方法,但它看起来并不像你实际使用它们一样。
来自文档:
成功打开后,数据库将被缓存,因此您可以在每次需要写入数据库时调用此方法。 (确保在不再需要数据库时调用close()。)错误权限或完整磁盘等错误可能导致此方法失败,但如果问题得到解决,将来的尝试可能会成功。 数据库升级可能需要很长时间,您不应该从应用程序主线程调用此方法,包括来自ContentProvider.onCreate()。
答案 1 :(得分:0)
如果您查看了getReadableDatabase的文档,则说明
与getWritableDatabase()一样,此方法可能需要很长时间才能返回,因此您不应该从应用程序主线程调用它,包括来自ContentProvider.onCreate()
我在你的程序中看到的,首先你是在DBAdapter的构造函数中调用它
this.DBHelper = new DatabaseHelper(this.context);
this.DBHelper.getWritableDatabase();
this.DBHelper.getReadableDatabase();
然后在onCreate中调用db.open();你再次调用this.DBHelper.getWritableDatabase();
因此,您的数据库可能无法正确加载。并尝试在后台线程ex AsyncTask中执行所有此操作。
希望这有帮助!!!