2012-10-18 83 views
4

光標我有這樣的數據庫使用SQLite,和我在與關閉遊標的話說,Application did not close the cursor or database object that was opened here這裏的logcat的如何正確關閉機器人

10-18 08:40:56.354: E/Cursor(331): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210) 
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53) 
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345) 
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229) 
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184) 
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264) 
10-18 08:40:56.354: E/Cursor(331): at standard.internet.marketing.mymovingfriend.SQLHandler.checkMove(SQLHandler.java:1094) 
10-18 08:40:56.354: E/Cursor(331): at standard.internet.marketing.mymovingfriend.ListMovingNames$3.onKey(ListMovingNames.java:98) 
10-18 08:40:56.354: E/Cursor(331): at android.view.View.dispatchKeyEvent(View.java:3735) 
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788) 
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788) 
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788) 
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788) 
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1667) 
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1102) 
10-18 08:40:56.354: E/Cursor(331): at android.app.Activity.dispatchKeyEvent(Activity.java:2063) 
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643) 
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471) 
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441) 
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewRoot.handleMessage(ViewRoot.java:1735) 
10-18 08:40:56.354: E/Cursor(331): at android.os.Handler.dispatchMessage(Handler.java:99) 
10-18 08:40:56.354: E/Cursor(331): at android.os.Looper.loop(Looper.java:123) 
10-18 08:40:56.354: E/Cursor(331): at android.app.ActivityThread.main(ActivityThread.java:4627) 
10-18 08:40:56.354: E/Cursor(331): at java.lang.reflect.Method.invokeNative(Native Method) 
10-18 08:40:56.354: E/Cursor(331): at java.lang.reflect.Method.invoke(Method.java:521) 
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
10-18 08:40:56.354: E/Cursor(331): at dalvik.system.NativeStart.main(Native Method) 

這個問題一直纏着我3天的問題。

這裏的一些相關代碼:

public class SQLHandler { 

    public static final String KEY_MOVENAME = "movename"; 
    public static final String KEY_ID1 = "_id"; 
    public static final String KEY_ID5 = "_id"; 
    public static final String KEY_MOVEDATE = "movedate"; 
    public static final String KEY_TOTALMOVEWEIGHT = "totalmoveweight"; 
    public static final String KEY_TOTALITEM = "totalitem"; 

    private static final String DATABASE_NAME = "mymovingfriend"; 
    private static final int DATABASE_VERSION = 1; 

    public static final String KEY_LISTITEMNAME = "listitemname"; 
    public static final String KEY_LISTITEMWEIGHT = "listitemweight"; 
    public static final String KEY_LISTITEMROOM = "listitemroom"; 

    private static final String DATABASE_TABLE1 = "movingname"; 
    private static final String DATABASE_TABLE5 = "listitem"; 

    public static final String CREATE_TABLE_1 = "CREATE TABLE " + DATABASE_TABLE1 + " (" + 
      KEY_ID1 + " INTEGER PRIMARY KEY AUTOINCREMENT," + 
      KEY_MOVEDATE + " TEXT NOT NULL, " + 
      KEY_TOTALMOVEWEIGHT + " TEXT NOT NULL, " + 
      KEY_TOTALITEM + " INTEGER NOT NULL, " + 
      KEY_MOVENAME + " TEXT NOT NULL);"; 

    public static final String CREATE_TABLE_2 = "CREATE TABLE " + DATABASE_TABLE2 + " (" + 
      KEY_ID2 + " INTEGER PRIMARY KEY AUTOINCREMENT," + 
      KEY_ROOMMOVEHOLDER + " TEXT NOT NULL, " + 
      KEY_ROOMWEIGHT + " TEXT NOT NULL, " + 
      KEY_ROOM + " TEXT NOT NULL);"; 

    public static final String CREATE_TABLE_5 = "CREATE TABLE " + DATABASE_TABLE5 + " (" + 
      KEY_ID5 + " INTEGER PRIMARY KEY AUTOINCREMENT," + 
      KEY_LISTITEMNAME + " TEXT NOT NULL, " + 
      KEY_LISTITEMWEIGHT + " TEXT NOT NULL, " + 
      KEY_LISTITEMROOM + " TEXT NOT NULL);"; 

    private DbHelper ourHelper; 
    private final Context ourContext; 
    private SQLiteDatabase ourDatabase; 

    private static class DbHelper extends SQLiteOpenHelper{ 

     public DbHelper(Context context) { 
      super(context, DATABASE_NAME, null, DATABASE_VERSION); 
      // TODO Auto-generated constructor stub 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 
      // TODO Auto-generated method stub 
      db.execSQL(CREATE_TABLE_1); 
      db.execSQL(CREATE_TABLE_2); 
      db.execSQL(CREATE_TABLE_3); 
      db.execSQL(CREATE_TABLE_4); 
      db.execSQL(CREATE_TABLE_5); 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) { 
      // TODO Auto-generated method stub 
      db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE1); 
      db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE2); 
      db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE3); 
      db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE4); 
      db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE5); 
      onCreate(db); 
     } 
    } 

    public SQLHandler(Context c){ 
     ourContext = c; 
    } 

    public SQLHandler open() throws SQLException{ 
     ourHelper = new DbHelper(ourContext); 
     ourDatabase = ourHelper.getWritableDatabase(); 
     return this; 
    } 

    public void close(){ 
     ourDatabase.close(); 
     ourHelper.close(); 
    } 

    public long createMove(String smovename){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_MOVENAME, smovename); 
     cv.put(KEY_MOVEDATE, "Not yet set"); 
     cv.put(KEY_TOTALMOVEWEIGHT, "0"); 
     cv.put(KEY_TOTALITEM, 0); 
     return ourDatabase.insert(DATABASE_TABLE1, null, cv); 
    } 

    public void createList(){ 

     String[] sroom = new String[]{"Kitchen", "Bedroom", "Dinning Room"}; 
     String[] sitem = new String[]{"Dishwasher", "Bed", "Table"}; 
     String[] sweight = new String[]{"40", "25", "15"}; 

     for (int i = 0; i < sroom.length; i++) { 
      cv.put(KEY_LISTITEMROOM, sroom[i]); 
      cv.put(KEY_LISTITEMNAME, sitem[i]); 
      cv.put(KEY_LISTITEMWEIGHT, sweight[i]); 
      ourDatabase.insert(DATABASE_TABLE5, null, cv); 
     } 
    } 

    public void setMoveDate(String smovedate, String smovename){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_MOVEDATE, smovedate); 
     ourDatabase.update(DATABASE_TABLE1, cv, KEY_MOVENAME + "='" + smovename + "'", null); 
    } 

    public void setMoveWeight(String smoveweight, String smovename){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_TOTALMOVEWEIGHT, smoveweight); 
     ourDatabase.update(DATABASE_TABLE1, cv, KEY_MOVENAME + "='" + smovename + "'", null); 
    } 

    public void setTotalItem(String smovename, int imoveitem){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_TOTALITEM, imoveitem); 
     ourDatabase.update(DATABASE_TABLE1, cv, KEY_MOVENAME + "='" + smovename + "'", null); 
    } 

    public void renameRoom(String movename, String roomname, String currentroom){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_ROOM, roomname); 
     ourDatabase.update(DATABASE_TABLE2, cv, KEY_ROOMMOVEHOLDER + "='" + movename + "'" + " AND " + KEY_ROOM + "='" + currentroom + "'", null); 
    } 

    public void setRoomWeight(String sroomweight, String smovename, String sroomname){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_ROOMWEIGHT, sroomweight); 
     ourDatabase.update(DATABASE_TABLE2, cv, KEY_ROOMMOVEHOLDER + "='" + smovename + "'" + " AND " + KEY_ROOM + "='" + sroomname + "'", null); 
    } 

    public long addRooms(String sroommoveholder, String sroom){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_ROOMMOVEHOLDER, sroommoveholder); 
     cv.put(KEY_ROOM, sroom); 
     cv.put(KEY_ROOMWEIGHT, "0"); 
     return ourDatabase.insert(DATABASE_TABLE2, null, cv); 
    } 

    public long addNewItems(String sitemmoveholder, String sroomholder, String sitemname, String sitemvalue, String sitemweight){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_ITEMMOVEHOLDER, sitemmoveholder); 
     cv.put(KEY_ROOMHOLDER, sroomholder); 
     cv.put(KEY_ITEMNAME, sitemname); 
     cv.put(KEY_ITEMVALUE, sitemvalue); 
     cv.put(KEY_ITEMWEIGHT, sitemweight); 
     return ourDatabase.insert(DATABASE_TABLE3, null, cv); 
    } 

    public void updateItems(String sitemmoveholder, String sroomholder, String sitemname, String sitemvalue, String sitemweight){ 
     ContentValues cv = new ContentValues(); 
     cv.put(KEY_ITEMVALUE, sitemvalue); 
     cv.put(KEY_ITEMWEIGHT, sitemweight); 
     ourDatabase.update(DATABASE_TABLE3, cv, KEY_ITEMMOVEHOLDER + "='" + sitemmoveholder + "'" + " AND " + 
       KEY_ROOMHOLDER + "='" + sroomholder + "'" + " AND " + KEY_ITEMNAME + "='" + sitemname + "'", null); 
    } 

    public Cursor getMove(){ 
     String[] columns = new String[]{KEY_ID1, KEY_MOVENAME}; 

     Cursor c = null; 
     try { 
      c = ourDatabase.query(DATABASE_TABLE1, columns, null, null, null, null, null); 
     } catch (Exception e) { 
      c.close(); 
     } 
     return c; 
    } 

    public String getTotalWeight(String m) throws SQLException{ 
     String[] columns = new String[]{KEY_ID1, KEY_MOVENAME, KEY_MOVEDATE, KEY_TOTALMOVEWEIGHT}; 

     Cursor c = null; 
     try { 
      c = ourDatabase.query(DATABASE_TABLE1, columns, KEY_MOVENAME + "= '" + m + "'", null, null, null, null); 
      if (c != null) { 
       c.moveToFirst(); 
       String totalWeight = c.getString(3); 
       return totalWeight; 
      } 
     } catch (Exception e) { 
      c.close(); 
     } 
     return null; 

    } 

    public String getTotalWeightLBS(String m) throws SQLException{ 
     String[] columns = new String[]{KEY_ID1, KEY_MOVENAME, KEY_MOVEDATE, KEY_TOTALMOVEWEIGHT}; 

     Cursor c = null; 
     try { 
      c = ourDatabase.query(DATABASE_TABLE1, columns, KEY_MOVENAME + "= '" + m + "'", null, null, null, null); 
      if (c != null) { 
       c.moveToFirst(); 
       int x = Integer.parseInt(c.getString(3)) * 7; 
       String totalWeight = "" + x + " lbs"; 
       return totalWeight; 
      } 
     } catch (Exception e) { 
      c.close(); 
     } 
     return null; 

    } 

    public String getDateMove(String md){ 
     String[] columns = new String[]{KEY_ID1, KEY_MOVENAME, KEY_MOVEDATE}; 

     Cursor c = null;try { 
      c = ourDatabase.query(DATABASE_TABLE1, columns, KEY_MOVENAME + "= '" + md + "'", null, null, null, null); 

      if (c != null) { 
       c.moveToFirst(); 
       String moveDate = c.getString(2); 
       return moveDate; 
      } 
     } catch (Exception e) { 
      c.close(); 
     } 
     return null; 
    } 

    public ArrayList<String> loadRooms(String mn) throws SQLException{ 
     String[] columns = new String[]{KEY_ID2, KEY_ROOMMOVEHOLDER, KEY_ROOM}; 

     ArrayList<String> array = new ArrayList<String>(); 

     Cursor c = null; 
     try { 
      c = ourDatabase.query(DATABASE_TABLE2, columns,KEY_ROOMMOVEHOLDER + "='" + mn + "'", 
        null, null, null, null); 
      int iroom = c.getColumnIndex(KEY_ROOM); 

      for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { 
       array.add(c.getString(iroom)); 
      } 
     } catch (Exception e) { 
      c.close(); 
     } 
     return array; 
    } 

    public void deleteMove(String m) throws SQLException{ 
     ourDatabase.delete(DATABASE_TABLE1, KEY_MOVENAME + "='" + m + "'", null); 
     ourDatabase.delete(DATABASE_TABLE2, KEY_ROOMMOVEHOLDER + "='" + m + "'", null); 
     ourDatabase.delete(DATABASE_TABLE3, KEY_ITEMMOVEHOLDER + "='" + m + "'", null); 
     ourDatabase.delete(DATABASE_TABLE4, KEY_TODOMOVE + "='" + m + "'", null); 
    } 

    public ArrayList<String> getitems(){ 
     String[] columns = new String[]{KEY_ID5, KEY_ITEMNAME}; 
     ArrayList<String> items; 
     items = new ArrayList<String>(); 

     Cursor c = null; 
     try { 
      c = ourDatabase.query(DATABASE_TABLE5, columns, null, null, null, null, null); 

      for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { 
       items.add(c.getString(1)); 
      } 
     } catch (Exception e) { 
      c.close(); 
     } 

     return items; 
    } 

    public ArrayList<String> getitemweight(){ 
     String[] columns = new String[]{KEY_ID5, KEY_ITEMWEIGHT}; 
     ArrayList<String> items = new ArrayList<String>(); 

     Cursor c = null; 
     try { 
      c = ourDatabase.query(DATABASE_TABLE5, columns, null, null, null, null, null); 
      for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { 
       items.add(c.getString(1)); 
      } 
     } catch (Exception e) { 
      c.close(); 
     } 

     return items; 
    } 

    public ArrayList<String> getitemclass(){ 
     String[] columns = new String[]{KEY_ID5, KEY_LISTITEMROOM}; 
     ArrayList<String> items = new ArrayList<String>(); 

     Cursor c = null; 
     try { 
      c = ourDatabase.query(DATABASE_TABLE5, columns, null, null, null, null, null); 

      for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { 
       items.add(c.getString(1)); 
      } 
     } catch (Exception e) { 
      c.close(); 
     } 

     return items; 
    } 

} 

回答

16

你不關閉光標在getDateMovegetTotalWeightLBSloadRooms ...

無處不在不需要光標再關閉它。在這些方法中使用try-finally,即使拋出異常發生時,也能保證在finally塊中執行代碼。在你的方法

更改代碼從這個:

try{ 
    // get data from cursor 
} catch (Exception e) { 
    c.close(); 
} 

這樣:

try { 
    // get data from cursor 
} catch (Exception e) { 
    // exception handling 
} finally { 
    if(c != null){ 
     c.close(); 
    } 
} 
+0

好吧我會嘗試這一個,謝謝... – philip

+0

對不起,先生,但它不工作... – philip

+0

等我發了一個錯字,修復它只是一秒 – philip

9

finally關閉光標將保證它會被關閉;

public void myfunc() { 

    Cursor c = null; 

    try { 

     c = ... // Open cursor here 
     return .... // maybe return something 

    } finally { 
     if(c != null) { c.close(); } 
    } 
} 
+0

它不工作先生... – philip

+0

爲什麼打開遊標try塊裏面? – Malachiasz

0

關閉數據庫在活動onStop()onDestroy()方法!

0

您嘗試使用

catch (Exception e) { 
      c.close(); 
     } 

關閉catch塊光標,但如果你沒有沒有得到任何異常,那麼它將如何關閉

所以把它放在最後內部的塊

finally { 
      c.close(); 
     } 
+0

幾個小時前試過這個,但仍然不能正常工作 – philip

+0

哦,然後嘗試從查詢中獲得Cursor後調用'startManagingCursor()'。 – subodh

+0

已經做到了這一點,光標是一個錯誤接縫是從數據庫中,而不是從活動 – philip

0

試試這個,

onStop()onDestroy()

檢查光標是否爲空

@Override 
public void onStop(){ 
Cursor cursor; 

if(cursor!=null){ 
    cursor.close();} 
} 

如果沒有,那麼關閉遊標。

編輯

關閉數據庫對象

DatabaseObject db; 
if(db!=null) 
{ db.close();} 

希望它能幫助。

+0

光標昨天嘗試這一個它不工作 – philip

+0

哦,我明白了。嘗試關閉你的數據庫對象以及 – GoCrazy

+0

我該怎麼做? – philip

4

如果一個元素被實施AutoCloseable(如Cursor.class一樣),我會建議做一個try-with-resources,像描述here。 如果您使用Retrolambda,則它有try-with-resources backported。

所以,你的代碼:

Cursor cursor = db.query("tableName", columns, null, null, null, null, null); 
try { 
    if (cursor.moveToFirst()) return cursor.getString(3); 
    else return null; 
} finally { 
    cursor.close(); 
} 

只會變成:

try (Cursor cursor = db.query("tableName", columns, null, null, null, null, null)) { 
    if (cursor.moveToFirst()) return cursor.getString(3); 
    else return null; 
} 
+1

作爲一個說明,這種方法需要API 19 –

+1

Im使用它與API 11,並沒有收到崩潰,而最近幾個月約3k用戶。 –

+0

Android Studio的檢查員通過「試用資源需要API級別19(當前最小值爲15)」突出顯示紅色的嘗試,但是我測試了它,並且它在電話API級別17上編譯並運行良好。顯然,它不應該是支持minAPI <19。 http://stackoverflow.com/questions/20480090/does-android-support-jdk-6-or-7/22303654#22303654雖然它可能在某些設備上工作,但不應該推薦它。 – Murphy