处理 SQLite 数据库的多个对象
Handle multiple objects for SQLite Database
我试图在 thread.But 中多次更新单个 SQLite 行项目,它抛出 close() was never explicitly called on database error.. 我做到了我的逻辑如下:
ta.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {}
@Override
public void afterTextChanged(final Editable s) {
// TODO Auto-generated method stub
Thread textThread = new Thread(new Runnable() {
@Override
public void run() {
mValues.open();
mValues.updateText(id, s.toString());
mValues.close();
}
});textThread.start();
Editor edittextEditor = checkPrefs.edit();
edittextEditor.putString(IncidentQuestionPage.EDITTEXT_KEY+id, s.toString());
edittextEditor.commit();
}
});
来自数据库的 updateText()、open() 和 close():
public IncidentValues open() throws SQLException {
ourHelper = new DbHelper(context);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close() {
ourHelper.close();
}
public void updateText(String optionId, String text){
ContentValues data=new ContentValues();
data.put(VALUE, text);
ourDatabase.update(INCIDENT_VALUES_TABLE, data, INCIDENT_OPTION_ID+"=?", new String[] {optionId});
}
在 EditText 中更改数据后的Logcat:
02-14 13:36:36.059: E/SQLiteDatabase(3679): close() was never explicitly called on database '/data/data/com.mondaz.globalfocusfocalpoint/databases/IncidentValues'
02-14 13:36:36.059: E/SQLiteDatabase(3679): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1944)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:800)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at com.mondaz.globalfocusfocalpoint.localDb.IncidentValues.open(IncidentValues.java:62)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at com.mondaz.globalfocusfocalpoint.adapter.IncidentQuestionAdapter.run(IncidentQuestionAdapter.java:221)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at java.lang.Thread.run(Thread.java:856)
02-14 13:36:36.060: E/System(3679): Uncaught exception thrown by finalizer
02-14 13:36:36.061: E/System(3679): java.lang.IllegalStateException: Don't have database lock!
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2091)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.entryRemoved(SQLiteDatabase.java:2183)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.entryRemoved(SQLiteDatabase.java:2179)
02-14 13:36:36.061: E/System(3679): at android.util.LruCache.trimToSize(LruCache.java:197)
02-14 13:36:36.061: E/System(3679): at android.util.LruCache.evictAll(LruCache.java:285)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2144)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1915)
02-14 13:36:36.061: E/System(3679): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
02-14 13:36:36.061: E/System(3679): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
02-14 13:36:36.061: E/System(3679): at java.lang.Thread.run(Thread.java:856)
我曾尝试将 Thread.sleep(1000)
放入线程中,但没有成功。
请建议如何处理这个多个数据库对象..
简单的解决方案:
不需要每次从线程 open/close 数据库。您应该必须在 onResume()
中打开数据库并在 onPause()
中关闭它以处理多个数据库实例。
简单更改您的代码来自:
@Override
public void run() {
mValues.open();
mValues.updateText(id, s.toString());
mValues.close();
}
至
@Override
public void run() {
mValues.updateText(id, s.toString());
}
然后按照我的建议打开和关闭数据库。
类似于:
//Open the Db when the Activity resumes
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
dbInstance.open();
}
//Closethe it when the Activity pauses
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
dbInstance.close();
}
编辑
我认为这个解决方案足以在适配器中处理它。或者您可以在适配器 class 中为打开和关闭创建两个用户定义的方法,并分别从 activity onResume() 和 onPause() 调用它们。类似于:
//for open
public void openDatabase(){
dbInstance.open();
}
// //for close
public void closeDatabase(){
dbInstance.close();
}
并从 activity.
调用它们
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mAdapter.closeDatabase();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mAdapter.openDatabase();
}
试试吧。应该可以。
我试图在 thread.But 中多次更新单个 SQLite 行项目,它抛出 close() was never explicitly called on database error.. 我做到了我的逻辑如下:
ta.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {}
@Override
public void afterTextChanged(final Editable s) {
// TODO Auto-generated method stub
Thread textThread = new Thread(new Runnable() {
@Override
public void run() {
mValues.open();
mValues.updateText(id, s.toString());
mValues.close();
}
});textThread.start();
Editor edittextEditor = checkPrefs.edit();
edittextEditor.putString(IncidentQuestionPage.EDITTEXT_KEY+id, s.toString());
edittextEditor.commit();
}
});
来自数据库的 updateText()、open() 和 close():
public IncidentValues open() throws SQLException {
ourHelper = new DbHelper(context);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close() {
ourHelper.close();
}
public void updateText(String optionId, String text){
ContentValues data=new ContentValues();
data.put(VALUE, text);
ourDatabase.update(INCIDENT_VALUES_TABLE, data, INCIDENT_OPTION_ID+"=?", new String[] {optionId});
}
在 EditText 中更改数据后的Logcat:
02-14 13:36:36.059: E/SQLiteDatabase(3679): close() was never explicitly called on database '/data/data/com.mondaz.globalfocusfocalpoint/databases/IncidentValues'
02-14 13:36:36.059: E/SQLiteDatabase(3679): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1944)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:800)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at com.mondaz.globalfocusfocalpoint.localDb.IncidentValues.open(IncidentValues.java:62)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at com.mondaz.globalfocusfocalpoint.adapter.IncidentQuestionAdapter.run(IncidentQuestionAdapter.java:221)
02-14 13:36:36.059: E/SQLiteDatabase(3679): at java.lang.Thread.run(Thread.java:856)
02-14 13:36:36.060: E/System(3679): Uncaught exception thrown by finalizer
02-14 13:36:36.061: E/System(3679): java.lang.IllegalStateException: Don't have database lock!
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2091)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.entryRemoved(SQLiteDatabase.java:2183)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.entryRemoved(SQLiteDatabase.java:2179)
02-14 13:36:36.061: E/System(3679): at android.util.LruCache.trimToSize(LruCache.java:197)
02-14 13:36:36.061: E/System(3679): at android.util.LruCache.evictAll(LruCache.java:285)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2144)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
02-14 13:36:36.061: E/System(3679): at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1915)
02-14 13:36:36.061: E/System(3679): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
02-14 13:36:36.061: E/System(3679): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
02-14 13:36:36.061: E/System(3679): at java.lang.Thread.run(Thread.java:856)
我曾尝试将 Thread.sleep(1000)
放入线程中,但没有成功。
请建议如何处理这个多个数据库对象..
简单的解决方案:
不需要每次从线程 open/close 数据库。您应该必须在 onResume()
中打开数据库并在 onPause()
中关闭它以处理多个数据库实例。
简单更改您的代码来自:
@Override
public void run() {
mValues.open();
mValues.updateText(id, s.toString());
mValues.close();
}
至
@Override
public void run() {
mValues.updateText(id, s.toString());
}
然后按照我的建议打开和关闭数据库。 类似于:
//Open the Db when the Activity resumes
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
dbInstance.open();
}
//Closethe it when the Activity pauses
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
dbInstance.close();
}
编辑
我认为这个解决方案足以在适配器中处理它。或者您可以在适配器 class 中为打开和关闭创建两个用户定义的方法,并分别从 activity onResume() 和 onPause() 调用它们。类似于:
//for open
public void openDatabase(){
dbInstance.open();
}
// //for close
public void closeDatabase(){
dbInstance.close();
}
并从 activity.
调用它们@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mAdapter.closeDatabase();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mAdapter.openDatabase();
}
试试吧。应该可以。