我正在创建一个应用程序。我收到了这个错误:
11-08 13:46:24.665:ERROR / Database(443): java.lang.IllegalStateException: /data/data/com.testproj/databases/Testdb创建的SQLiteDatabase和 从未关闭
我似乎无法找到原因,因为有些时候会显示错误,有时则不然。这是我的代码:
public class SQLiteAssistant extends SQLiteOpenHelper {
public SQLiteAssistant(Context context){
super(context, DB_NAME, null, DB_VERSION_NUMBER);
this.myContext = context;
}
public void openDataBase() throws SQLException{
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
public void closeDataBase() {
if(this.myDataBase != null) {
if(this.myDataBase.isOpen())
this.myDataBase.close();
}
}
}
}
在另一堂课中,我有这些疑问:
public class Db{
private static SQLiteAssistant sqlite;
public static String getSomeString(Context ctx) {
sqlite = new SQLiteAssistant(ctx);
sqlite.openDataBase();
Cursor cursor = sqlite.myDataBase.rawQuery("SELECT someColumn from SomeTable",null);
if (cursor != null) {
if (cursor.getCount()==1) {
if(cursor.moveToFirst()) {
String testString = cursor.getString(cursor.getColumnIndex("someColumn"));
cursor.close();
sqlite.closeDataBase();
sqlite.close();
return testString
}
}
}
sqlite.closeDataBase();
sqlite.close();
return null;
}
}
我的问题是当我开始一项新的活动时,我得到AsyncTask
。此任务从Web服务获取数据并访问String
的数据库。这是AsyncTask
:
protected class BackTask extends AsyncTask<Context, String, String> {
@Override
protected String doInBackground(Context... params) {
try{
//get requeste data from the database
//access the web service
return result;
} catch (Exception e) {
return null;
}
return null;
}
}
如果我让活动顺其自然,一切都会好起来的。如果我没有并快速按下后退按钮,我会收到错误消息。关于如何解决这个问题的任何建议?
答案 0 :(得分:4)
我不确定您是否正确使用SQLiteOpenHelper
...您不需要myDataBase
字段,我们的想法是它为您管理数据库连接。不要以这种方式继承...除非你在onCreate()
等处做过没有在这里发布的事情,看起来你可以直接使用SQLiteOpenHelper
,即:
SQLiteOpenHelper sqlite = new SQLiteOpenHelper(ctx, DB_PATH+DB_NAME, null,
DB_VERSION_NUMBER);
假设结束活动也应该停止后台任务,我建议您从Activity.onPause()
拨打AsyncTask.cancel(true)
。确保从onCancelled()清除数据库。
如果你的后台任务是读取数据库的唯一内容,那么让它拥有SQLiteOpenHelper实例。静态数据容易陷入困境,所以最好避免恕我直言。我会做这样的事情:
protected class BackTask extends AsyncTask<String, Integer, String>
{
private SQLiteOpenHelper sqlite;
public void BackTask(Context ctx) {
sqlite = new SQLiteOpenHelper(ctx, DB_PATH+DB_NAME, null,
DB_VERSION_NUMBER);
}
@Override
protected String doInBackground(String... params)
{
try {
//get requeste data from the database
//access the web service
return result;
} catch (Exception e) {
}
return null;
}
@Override
protected void onCancelled() {
sqlite.close();
}
@Override
protected void onPostExecute(String result)
sqlite.close();
// Update UI here
}
}
答案 1 :(得分:2)
我认为这部分:
cursor.close();
sqlite.closeDataBase();
sqlite.close();
必须在最后关闭
Try{
//Do something
}
catch(){
//Catch exception
}
finally{
//Close cursor or/and eventually close database if you don't need it in the future
}
另外不要忘记在onDestroy方法中关闭数据库。
onCreate(Bundle b){
//create database instance
}
onDestroy{
//close db
}