2011-12-16 66 views
9

我已经使用Cursor从数据库中提取记录。这是完美的工作。如何安全关闭光标和数据库?

12-16 14:49:20.774: E/Database(18611): close() was never explicitly called on database '/data/data/com.android.application/databases/appZ.db' 
12-16 14:49:20.774: E/Database(18611): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810) 
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817) 
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851) 
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844) 
12-16 14:49:20.774: E/Database(18611): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540) 
12-16 14:49:20.774: E/Database(18611): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) 
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98) 
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158) 
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.DBHelper.fetchAll(DBHelper.java:91) 
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.ApplicationActivity.sc_adapter(ApplicationActivity.java:1210) 
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.ApplicationActivity.refresh_data(ApplicationActivity.java:1195) 
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.ApplicationActivity.onKeyDown(ApplicationActivity.java:1440) 
12-16 14:49:20.774: E/Database(18611): at android.view.KeyEvent.dispatch(KeyEvent.java:1037) 
12-16 14:49:20.774: E/Database(18611): at android.app.Activity.dispatchKeyEvent(Activity.java:2068) 
12-16 14:49:20.774: E/Database(18611): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643) 
12-16 14:49:20.774: E/Database(18611): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471) 
12-16 14:49:20.774: E/Database(18611): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441) 
12-16 14:49:20.774: E/Database(18611): at android.view.ViewRoot.handleMessage(ViewRoot.java:1735) 
12-16 14:49:20.774: E/Database(18611): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-16 14:49:20.774: E/Database(18611): at android.os.Looper.loop(Looper.java:123) 
12-16 14:49:20.774: E/Database(18611): at android.app.ActivityThread.main(ActivityThread.java:4627) 
12-16 14:49:20.774: E/Database(18611): at java.lang.reflect.Method.invokeNative(Native Method) 
12-16 14:49:20.774: E/Database(18611): at java.lang.reflect.Method.invoke(Method.java:521) 
12-16 14:49:20.774: E/Database(18611): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
12-16 14:49:20.774: E/Database(18611): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
12-16 14:49:20.774: E/Database(18611): at dalvik.system.NativeStart.main(Native Method) 

我refered东西从here - 但是,我同时我使用这个代码

public Cursor fetchAll() 
{ 
    SQLiteDatabase db = this.getReadableDatabase(); 
    Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior); 
    return cursor; 
} 

我logcat的是已经在logcat中的一些错误。他们告诉说使用getReadableDatabase()。我也使用这种方法。而且,我也用这个方法,

public Cursor fetchAll() 
{ 
    SQLiteDatabase db = this.getReadableDatabase(); 
    Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior); 
    if (cursor!=null) 
    { 
     cursor.close(); 
    } 
    if (db!=null) 
    { 
     db.close(); 
    } 
    return cursor; 
} 

这样有错误之后 -

Database wasn't open. 

后,还我在我的数据库已经这样的错误。所以有人告诉我如何在获取记录后获得光标和数据库的安全关闭。

回答

9

编辑:如果你返回一个已经关闭的游标,你不能使用它。在调用方法之前打开数据库,然后在调用方法后关闭游标然后关闭数据库。

您可以关闭游标你用它做这样的后:

Cursor cursor = fetchAll(); 
... // Do your work with the cursor 
cursor.close(); 

或者,如果你正在使用从活动的光标,而需要重新查询(重新启动活动时,停止......),你可以使用这个:

Cursor cursor = fetchAll(); 
startManagingCursor(cursor); // Android will take care of the cursor for you 
// Do your work with the cursor 

onDestroy()关闭数据库(关闭游标后,或者如果一个活动里面最好):

dbhelper.close(); 
1

您也可以参考answer(建议根据Activity的状态关闭游标/数据库对象连接的位置)或this one(建议如何关闭SQLiteDatabase对象)。当它已经写入一次时,无需详细说明。尽管如此,下面是编码部分的想法。每次当你调用这个方法,数据库将在读模式下打开你,但你没有关闭,这就是为什么收到此错误数据库时

if (dbCursor != null && dbCursor.moveToFirst()) { 
      try { 
           //do stuff 
      } catch (exceptions) { 
           //catch possible exceptions 
      } finally { 

       if (dbCursor != null && !dbCursor.isClosed()) { 
        dbCursor.close(); 
       } 
      } 
+2

这将关闭游标,而不是数据库。 – 2011-12-16 09:58:22

+0

是啊 - 你有没有读过这个问题的最后部分?引用:所以有人告诉我如何在获取记录后获得游标和数据库的安全关闭。 – hovanessyan 2011-12-16 10:01:48

1

。打开刚才曾经像onCreate()方法,并关闭在destroy()方法

同时可以获取行后关闭游标时,有没有更多的需要光标然后关闭并设置为null

2

更好的做法将在onResume()中打开并在onPause()中关闭它。

3

在扩展ContentProvider的类中,如果打开数据库连接 并将辅助程序设置为onCreate中的实例变量,则可以关闭数据库连接 。

@Override 
public boolean onCreate() { 
    mOpenHelper = getDBOpenHelper(); 
    return true; 
} 
@Override 
public void shutdown() { 
mOpenHelper.close(); 
    super.shutdown(); 
} 
0

尝试通过SQLiteDatabase作为参数传递给您的使用fetchall方法:

MyDatabase db = new MyDatabase(this); 

.... 

Cursor myCursor = db.fetchAll(db.getReadableDatabase()); 

myCursor.close(); 
db.close(); 




    public Cursor fetchAll(SQLiteDatabase db, String listName) { 
     String sql = "select ID _id, Name from ListName where Name = ? order by ID"; 
     Cursor c = db.rawQuery(sql, new String[] { listName }); 
     c.moveToFirst(); 

     return c; 
    }