0

I am trying to update a single SQLite row item multiple times in a thread.But it throwing close() was never explicitly called on database error.. I did my logic like below:

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() and close() from DB:

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});
}

The Logcat after changing data in EditText:

    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$2$1.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$1.entryRemoved(SQLiteDatabase.java:2183)
    02-14 13:36:36.061: E/System(3679):     at android.database.sqlite.SQLiteDatabase$1.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)

I have tried by putting Thread.sleep(1000) inside the thread, but it didn't work.

Please suggest how to handle this multiple database objects..

5
  • What do you mean with "multiple database objects"? In your code, all threads share one, without synchronization. Commented Feb 14, 2015 at 8:23
  • @CL. Thanks for reply. i apologize if I understood and wrote something wrong. As I know the thread is calling each time there is a new text adds in EditText..So I think its creating a new database object..then open it each time and do the update task and close.. Commented Feb 14, 2015 at 8:26
  • @DerGolem can you please suggest me that where to use ourDatabase.close(); ..I have closed the dbHelper i.e SQLiteOpenHelper.. Commented Feb 14, 2015 at 9:11
  • Thanks for your suggestion ...let me do this now.. Commented Feb 14, 2015 at 9:13
  • @DerGolem No... unfortunately Its showing the same error.. Actually the error is not affecting my app and not any force close, but its showing after putting text in edittext.. Commented Feb 14, 2015 at 11:36

1 Answer 1

1

Simple solution:

No need to open/close the db each time from thread. You should have to open the db in onResume() and close it in onPause() to handle multiple db instances.

Simple change your code From :

@Override
  public void run() {
    mValues.open();
    mValues.updateText(id, s.toString());                               
    mValues.close();

}

To

@Override
 public void run() {
  mValues.updateText(id, s.toString());                               

}

And just open and close the db as I suggested. Something like:

//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(); 
}

EDIT

I think this solution is enough to handle it in adapters. Or you can create two user defined methods in adapter class for both open and close and call them from activity onResume() and onPause() respectively.. something like:

//for open
public void openDatabase(){
    dbInstance.open();
}
// //for close
public void closeDatabase(){
    dbInstance.close();
}

and call them from 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();
}

Just try. It should work.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the solution. Can you suggest me how to do this from adapters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.