我有一个功能正常的应用程序,不会强行关闭或崩溃。但是当我看到LogCat时,它偶尔会给我这个:
05-20 15:24:55.338: E/SQLiteDatabase(12707): close() was never explicitly called on database '/data/data/com.---.--/databases/debt.db'
05-20 15:24:55.338: E/SQLiteDatabase(12707): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
一点点下来......
05-20 15:24:55.338: E/System(12707): Uncaught exception thrown by finalizer
05-20 15:24:55.338: E/System(12707): java.lang.IllegalStateException: Don't have database lock!
我不确定何时应该打开和关闭我的数据库?
我的主要活动只是一个启动画面。然后它进入一个使用来自DB的信息调用ListView的活动;所以它是这个活动,首先打开数据库。
还有一个其他活动,其中需要DB与ListVeew分支。什么时候我应该打开和关闭这个? Word似乎是我需要打开一次,然后在应用程序“暂停”,“停止”或“销毁”时关闭。
如果是这种情况,我在哪里将db.close()方法放在启动屏幕主要活动中,其中onStop等位于何处?或者与打开数据库的活动相同的活动?或..还有另一个地方吗?
更新:
这是错误指向的代码行:
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
答案 0 :(得分:9)
如果您正在使用DatabaseHelper类的实例,并且在初始化DBHelper对象之后,每次在数据库中工作时都应该在工作之前调用open方法,然后创建一个新游标,查询数据库,使用您刚刚存储在游标中的信息,当您完成关闭游标,然后关闭数据库。例如,如果您想要获取数据库中的每个项目,您可以执行以下操作:
...
DataBaseHelper db = new DataBaseHelper(this);
...
db.open();
Cursor cursor = db.getAllItems();
maxCount = cursor.getCount();
Random gen = new Random();
row = gen.nextInt(maxCount); // Generate random between 0 and max
if (cursor.moveToPosition(row)) {
String myString = cursor.getString(1); //here I want the second column
displayString(myString); //private method
}
cursor.close();
db.close();
getAllItems
是我DatabaseHelper
中的一种公共方法,如果你想知道它就是这样的
public Cursor getAllItems() {
return db.query(DATABASE_TABLE,
new String[] {
KEY_ROWID,
KEY_NAME
},
null,
null,
null,
null,
null);
}
这是我访问我的数据库的方式,我没有得到任何错误,而且效果很好。
答案 1 :(得分:2)
您可能无法正确处理数据库;您正在打开比关闭更多的数据库实例。
您可以遵循许多设计模式来纠正此行为。您可能需要咨询this answer以获取更多信息。
答案 2 :(得分:2)
我曾经按照上面提到的@Shikima的方式行事,但在具有许多后台服务,多线程等的复杂应用程序中,当你必须管理许多数据库实例时,它会变得非常烦人,最重要的是,打开和关闭它们。
为了解决这个问题,我使用了以下方法,似乎工作正常。
在Application基类中声明并初始化 YourDBHelperClass 的实例,如下所示:
public class App extends Application {
public static YourDBHelperClass db;
@Override
public void onCreate() {
super.onCreate();
db = new YourDBHelperClass(getApplicationContext());
db.open();
}
}
在您的活动或您想要使用数据库的任何其他地方,初始化YourDBHelperClass对象,如下所示:
YourDBHelperClass db = App.db;
然后您可以随意使用数据库,而无需担心每次都手动打开和关闭它。当应用程序被销毁时,SQLiteOpenHelper负责关闭