2012-06-24 56 views
1

我有一個程序,你點擊一個按鈕,並彈出一個對話框與一堆複選框。您選擇一些複選框,然後單擊「確定」。我試圖做的是讓它在按下ok時,對於每個檢查過的值,它將搜索多個數據庫表中包含該值的行,從這些行中獲取信息並將它們放入不同的表中。出於某種原因,我一直讓這個遊標超出界限例外,我真的不明白爲什麼。我嘗試了一些我在搜索時發現的東西,但無法使其工作。Android:光標出界異常

下面是當您單擊確定會發生什麼:

ok.setOnClickListener(new View.OnClickListener(){ 
    public void onClick(View v) { 

     if (dumbbells.isChecked()==true){ 
      equip = "dumbbells"; 
      AddToEquipTable(equip); 
     } 
     if (barbell.isChecked()==true){ 
      equip = "Barbell"; 
      AddToEquipTable(equip); 
     } 
     if (cablemachine.isChecked()==true){ 
      equip = "Cable Machine"; 
      AddToEquipTable(equip); 
     } 
     if (pullupbar.isChecked()==true){ 
      equip = "Pull Up Bar"; 
      AddToEquipTable(equip); 
     } 
     if (legpressmachine.isChecked()==true){ 
      equip = "Leg Press Machine"; 
      AddToEquipTable(equip); 
     } 
     if (legextensionmachine.isChecked()==true){ 
      equip = "Leg Extension Machine"; 
      AddToEquipTable(equip); 
     } 
     if (hamstringcurlmachine.isChecked()==true){ 
      equip = "Hamstring Curl Machine"; 
      AddToEquipTable(equip); 
     } 
     if (kettlebells.isChecked()==true){ 
      equip = "Kettlebells"; 
      AddToEquipTable(equip); 
     } 
     if (none.isChecked()==true){ 
      equip = "None"; 
      AddToEquipTable(equip); 
     } 


    } 
}); 

這裏是「AddToEquipTable」的方法,我創建:

public void AddToEquipTable(String equip){ 

ExerciseDatabase equipment = new ExerciseDatabase(WorkMeOutActivity.this); 
try { 
    equipment.open(); 
} catch (SQLException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

equipment.AddToEquipmentDBFromBiceps(equip); 
equipment.AddToEquipmentDBFromChest(equip); 
equipment.AddToEquipmentDBFromBack(equip); 
equipment.AddToEquipmentDBFromTriceps(equip); 
equipment.AddToEquipmentDBFromShoulders(equip); 
equipment.AddToEquipmentDBFromLegs(equip); 
equipment.AddToEquipmentDBFromCompound(equip); 

equipment.close(); 
} 

這裏是它在我的數據庫輔助函數的方法之一活動。它們都是一樣的,除了名稱叫做表格名稱。

public String AddToEquipmentDBFromBiceps(String equip) { 
    // TODO Auto-generated method stub 
    String[] columns = new String[]{KEY_REPS, KEY_EXERCISE, KEY_TIMETYPE}; 
    ContentValues cv = new ContentValues(); 
    Cursor c = ourDatabase.query(DATABASE_BICEPSTABLE, columns, KEY_EQUIP + "='" + equip + "'", null, null, null, null); 

    if (c == null){ 
     return null; 
    } 
    else if(c != null){ 

     c.moveToFirst(); 

     int iReps = c.getColumnIndex(KEY_REPS); 
     int iExercise = c.getColumnIndex(KEY_EXERCISE); 
     int iTimeType = c.getColumnIndex(KEY_TIMETYPE); 



     do{ 

      String reps = c.getString(iReps); 
      String exercise = c.getString(iExercise); 
      String time = c.getString(iTimeType); 

      cv.put(KEY_REPS, reps); 
      cv.put(KEY_EXERCISE, exercise); 
      cv.put(KEY_TIMETYPE, time); 

      ourDatabase.insert(DATABASE_CHOSEN_EQUIP_TABLE, null, cv); 

      c.moveToNext(); 

      }while(KEY_EQUIP == equip); 
     } 


    return null; 
} 

**錯誤日誌變更條件的建議下面後:

while (c.moveToNext() && KEY_EQUIP == equip); 


注:此外,我建議

06-24 09:34:42.785: E/AndroidRuntime(20592): FATAL EXCEPTION: main 
06-24 09:34:42.785: E/AndroidRuntime(20592): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at com.work.me.out.ExerciseDatabase.AddToEquipmentDBFromLegs(ExerciseDatabase.java:896) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at com.work.me.out.WorkMeOutActivity.AddToEquipTable(WorkMeOutActivity.java:456) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at com.work.me.out.WorkMeOutActivity$9.onClick(WorkMeOutActivity.java:395) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.view.View.performClick(View.java:2538) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.view.View$PerformClick.run(View.java:9152) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.os.Handler.handleCallback(Handler.java:587) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.os.Handler.dispatchMessage(Handler.java:92) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.os.Looper.loop(Looper.java:130) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at android.app.ActivityThread.main(ActivityThread.java:3687) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at java.lang.reflect.Method.invokeNative(Native Method) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at java.lang.reflect.Method.invoke(Method.java:507) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 
06-24 09:34:42.785: E/AndroidRuntime(20592): at dalvik.system.NativeStart.main(Native Method) 

回答

5

也許你有不好的條件下,隨着你的改變給你使用更安全,更快,更清晰的parametrized statements


CursorIndexOutOfBoundsException:指數0請求,大小爲0

這意味着cursor.moveToFirst()返回false和Cursor是空的。 因此,請嘗試添加此代碼段並嘗試。

else if(c != null && c.moveToFirst()) { 
     int iReps = c.getColumnIndex(KEY_REPS); 
     int iExercise = c.getColumnIndex(KEY_EXERCISE); 
     int iTimeType = c.getColumnIndex(KEY_TIMETYPE); 
     do { 
      String reps = c.getString(iReps); 
      String exercise = c.getString(iExercise); 
      String time = c.getString(iTimeType); 

      cv.put(KEY_REPS, reps); 
      cv.put(KEY_EXERCISE, exercise); 
      cv.put(KEY_TIMETYPE, time); 

      ourDatabase.insert(DATABASE_CHOSEN_EQUIP_TABLE, null, cv); 
      } while (c.moveToNext() && KEY_EQUIP == equip); 
     } 

嘗試使用類似這樣的rawQuery方法:

final String SELECT_QUERY = "SELECT " + KEY_REPS + ", " + KEY_EXERCISE + ", " + KEY_TIMETYPE + " FROM " + DATABASE_BICEPSTABLE + " WHERE " + KEY_EQUIP + " = ?"; 
Cursor c = db.rawQuery(SELECT_QUERY, new String[] {equip}); 
+0

我只是去嘗試......仍然得到同樣的光標出界外 – SillyFidget

+0

此處添加您的錯誤日誌。 – Sajmon

+0

看到我更新的答案並用我的替換你的條件片段。 – Sajmon

1

你必須確保你在遊標的第一行指向您嘗試訪問任何數據,特別是線c.getColumnIndex(KEY_XXX)前。你叫c.moveToFirst()沒有檢查它的結果(因爲沒有數據行而你的情況應該返回false。

if(c != null && c.moveToFirst()) { 
    int iReps = c.getColumnIndex(KEY_REPS); 
    int iExercise = c.getColumnIndex(KEY_EXERCISE); 
    int iTimeType = c.getColumnIndex(KEY_TIMETYPE); 

    do { 
     String reps = c.getString(iReps); 
     String exercise = c.getString(iExercise); 
     String time = c.getString(iTimeType); 

     cv.put(KEY_REPS, reps); 
     cv.put(KEY_EXERCISE, exercise); 
     cv.put(KEY_TIMETYPE, time); 

     ourDatabase.insert(DATABASE_CHOSEN_EQUIP_TABLE, null, cv);  
    } while(c.moveToNext() && KEY_EQUIP == equip); 
} else { 
    return null; 
} 

需要注意的是其重要的在這裏使用一個do..while循環,而不是一個普通while循環,如隨後調用由c.moveToFirst()c.moveToNext()意味着你缺少光標數據的第一行後直!