2015-02-14 3 views
0

Я пытаюсь обновить один элемент строки SQLite несколько раз в потоке. Но это бросание close() никогда не вызывалось явным образом при ошибке базы данных .. Я сделал свою логику, как показано ниже:Обрабатывать несколько объектов для базы данных SQLite

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(), открытый() и закрытия() из БД:

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

Logcat после изменения данных в 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) 

Я попытался поставить Thread.sleep(1000) внутри темы, но это не сработало.

Пожалуйста, подсказывают, как справиться с этим несколько объектов базы данных ..

+0

Что вы подразумеваете под «несколькими объектами базы данных»? В вашем коде все потоки разделяют один, без синхронизации. –

+0

@CL. Спасибо за ответ. Извиняюсь, если я понял и написал что-то не так. Поскольку я знаю, что поток вызывает каждый раз, когда добавляется новый текст в EditText..So, я думаю, что он создает новый объект базы данных. Затем открывайте его каждый раз и выполняйте задачу обновления и закрывайте. – user3678972

+0

@DerGolem вы можете предложите мне, где использовать 'ourDatabase.close();' .. Я закрыл 'dbHelper', то есть' SQLiteOpenHelper'. – user3678972

ответ

1

Простое решение:

Нет необходимости открывать/закрывать БД каждый раз из потока. Вам нужно открыть db в onResume() и закрыть его в onPause() для обработки нескольких экземпляров db.

Простое изменение вашего кода:

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

EDIT

Я думаю, что это решение достаточно, чтобы справиться с этим в адаптерах. Или вы можете создать два определяемые пользователем методы класса адаптера как для открытия и закрытия и называют их деятельности onResume() и OnPause() соответственно .. что-то вроде:

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

и вызывать их из деятельности.

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

Просто попробуйте. Он должен работать.

+0

Спасибо за решение. Можете ли вы предложить мне, как это сделать от адаптеров. – user3678972

+0

@ user3678972 проверить мой обновленный ответ. – Ranjit

Смежные вопросы