访问Sqlite数据库时出现CursorIndexOutOfBoundsException

时间:2011-08-19 13:32:28

标签: android sqlite cursor

大家好,我遇到了一些困难,希望你们中的一个可以提供帮助。我正在尝试创建一个小程序来存储我的大学时间表。我在使用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)

2 个答案:

答案 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中执行所有此操作。

希望这有帮助!!!