如何在 Android 中正确打开/关闭 SQLite 数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10677781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Open/Close SQLite db in Android Properly
提问by TheLettuceMaster
I have an app that functions properly and does not force close or crash. But when I look at LogCat, it occasionally gives me this:
我有一个应用程序可以正常运行并且不会强制关闭或崩溃。但是当我查看 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
a little ways down...
有点下降...
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!
I am not sure when I should be opening and closing my Database?
我不确定什么时候应该打开和关闭我的数据库?
I have a Main activity that is simply a splash screen. It then goes into an activity that calls a ListView using info from the DB; so it is at thisactivity where the DB is first opened.
我有一个主要的活动,它只是一个启动画面。然后它进入一个使用来自数据库的信息调用 ListView 的活动;所以在这个活动中首先打开数据库。
There is also one other Activity where the DB is required that branches off the one with the ListVeew. When am I supposed to be opening and closing this? Word seems to be that I simply need to open once, and then close when the app is "paused", "stopped" or "destroyed".
还有一个其他 Activity 需要数据库从 ListVeew 分支出来。我应该什么时候打开和关闭这个?词似乎是我只需要打开一次,然后在应用程序“暂停”、“停止”或“销毁”时关闭。
If this is the case, where do I put the db.close() method... in the Splash Screen Main Activity where onStop, etc is located? or the same Activity as the one that opens the DB? or.. is there another place?
如果是这种情况,我应该将 db.close() 方法放在哪里...在 onStop 等所在的启动画面主活动中?还是与打开数据库的活动相同的活动?或者……还有别的地方吗?
UPDATE:
更新:
This is the line in code that the error keeps pointing to:
这是错误一直指向的代码行:
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
采纳答案by Shikima
If you're using an instance of a DatabaseHelper class, and after you initialize the DBHelper object, every time you do work in the database you should call the open method before you do work, then create a new cursor, query the database, do work with the information you just stored in the cursor, when you're done close the cursor, then close the database. For example if you wanted to grab every item in a database you would do something like :
如果您使用的是 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
is a public method in my DatabaseHelper
, it looks like this in case you were wondering
getAllItems
是我的公共方法DatabaseHelper
,如果您想知道,它看起来像这样
public Cursor getAllItems() {
return db.query(DATABASE_TABLE,
new String[] {
KEY_ROWID,
KEY_NAME
},
null,
null,
null,
null,
null);
}
This is how I access my database and I haven't gotten any of the errors you've got, and it works perfectly.
这就是我访问我的数据库的方式,我没有遇到您遇到的任何错误,并且它运行良好。
回答by desidigitalnomad
I used to do the way @Shikima mentioned above but in complex applications which has many background services, multi-threading,etc it can get real tiresome when you have to manage many database instances and on top of that, opening and closing them.
我曾经采用上面提到的@Shikima 的方式,但是在具有许多后台服务、多线程等的复杂应用程序中,当您必须管理许多数据库实例并在此之上打开和关闭它们时,它会变得非常烦人。
To overcome this, I used the following method and it seems to be working fine.
为了克服这个问题,我使用了以下方法,它似乎工作正常。
1.
1.
Declare and initialize an instance of YourDBHelperClassin your Applicationbase class like this :
在您的Application基类中声明并初始化YourDBHelperClass 的一个实例,如下所示:
public class App extends Application {
public static YourDBHelperClass db;
@Override
public void onCreate() {
super.onCreate();
db = new YourDBHelperClass(getApplicationContext());
db.open();
}
}
2.
2.
In you activity, or any other place you want to use the DB, initialize the YourDBHelperClass object like this :
在您的活动或您想要使用数据库的任何其他地方,像这样初始化 YourDBHelperClass 对象:
YourDBHelperClass db = App.db;
And then you can use the database anyway you want without having to worry about opening and closing it manually each time. The SQLiteOpenHelpertakes care of the closing when the Application is destroyed
然后您可以随意使用数据库,而不必担心每次手动打开和关闭它。该SQLiteOpenHelper需要闭幕方面的应用被破坏时,
回答by Alex Lockwood
You are probably not handling your database correctly; you are opening more database instances than you are closing.
您可能没有正确处理您的数据库;您打开的数据库实例多于关闭的数据库实例。
There are a number of design patterns you can follow to correct this behavior. You might want to consult this answerfor more information.
您可以遵循许多设计模式来纠正这种行为。您可能需要查阅此答案以获取更多信息。