¿Cuán cuidado debo tener con el hilo de seguridad al crear métodos / actividades que interactúan con la base de datos SQLite?

Estoy creando una aplicación que permite que muchas Activities diferentes se inicie desde una TabActivity (hasta ~ 25). La mayoría de las actividades requieren datos de la base de datos sqlite, por lo que cuando onCreate se ejecuta, AsyncTask crea un objeto SQLiteOpenHelper (que abrirá una base de datos legible / grabable), ejecuta una consulta, recupera los datos y todo se cierra.

Solo estaba probando el desorden para ver si podía romper algo, así que TabActivity's cada Activity a la TabActivity's TabHost . Entonces comencé a machacar cada lengüeta lo más rápidamente posible.

Me di cuenta de que muy rápidamente comencé a ver en el LogCat: Caused by: android.database.sqlite.SQLiteException: database is locked: BEGIN EXCLUSIVE; Y la aplicación procedió a morir.

Normalmente sólo habrá alrededor de 4-6 pestañas (sólo puedo limitar el usuario de todos modos) para el TabHost . No he sido capaz de romper nada con una pequeña cantidad de pestañas para aplastar, pero todavía estoy preocupado de que tal vez estoy accediendo a la base de datos de una manera pobre.

¿Cómo puedo evitar que mis objetos de SQLiteDatabase provoquen un bloqueo?

Si creo un ContentProvider que eliminará la posibilidad de bloqueo de base de datos?

¿Tiene alguna sugerencia para los cambios que podría hacer para acceder a los datos de una SQLiteDatabase datos SQLiteDatabase ?

Terminé tomando el acercamiento de usar la clase de la Application y de almacenar 1 SQLiteOpenHelper y de intentar mi mejor para guardarlo sincronizado. Esto parece estar funcionando muy bien – pongo todas mis 25 actividades en TabHost y aplastadas en ellas sin errores.

Estoy llamando ((SQLiteDbApplication)getApplication()).setDbHelper(new DBHelper(this, Constants.DB_NAME, null, Constants.DB_VERSION_CODE)); Método (mostrado abajo) en cada onCreate() en mis actividades

¿Alguna otra sugerencia para este enfoque o para los cambios que hice usando esta clase de Application ?

 import android.app.Application; import android.database.sqlite.SQLiteDatabase; public class SQLiteDbApplication extends Application { private DBHelper dbHelper; private SQLiteDatabase db; public synchronized DBHelper getDbHelper() { db = dbHelper.getDatabase();//returns the already opened database object while(db.isDbLockedByCurrentThread() || db.isDbLockedByOtherThreads()); return dbHelper; } public synchronized void closeDb() { if(null != dbHelper) dbHelper.close(); if(null != db) db.close(); } @Override protected void finalize() throws Throwable { if(null != dbHelper) dbHelper.close(); if(null != db) db.close(); super.finalize(); } public synchronized void setDbHelper(DBHelper dbHelper) { if(null == this.dbHelper) { this.dbHelper = dbHelper; this.dbHelper.setDb(this.dbHelper.getWritableDatabase());//creates and sets the database object via getWritableDatabase() } } } 

Si usted está preocupado por todas las conexiones de la base de datos tratar de limitarse a un SqliteOpenHelper y asegúrese de envolver una capa de sincronización a su alrededor.

Puede extender la clase de aplicación y luego llamar a getApplication y lanzar el objeto que obtenga en su aplicación. Ahora puede almacenar un SqliteOpenHelper en esta clase de aplicación y crear su propio método de acceso seguro de subproceso a la conexión de base de datos.

Si está utilizando AsyncTask en todos sus métodos onCreate y tiene problemas con muchas pestañas, estos problemas también pueden ocurrir con un dispositivo más lento, un usuario más rápido o una base de datos que crece durante el tiempo de uso.

Dependiendo del caso de uso de su aplicación, puede ir a la manera de guardar y pasar por todo el esfuerzo y el dolor de roscar y bloqueo, o simplemente puede publicar la aplicación con un número de pestañas que nunca produjo el error y asegúrese de coger el Base de datos y envíese una notificación (por ejemplo a través de Google Analytics) para probar si el problema de subprocesos ocurre en el uso de la aplicación en la vida real.

Todas las devoluciones de llamadas de la actividad ocurren en el hilo principal, por lo que en el escenario que describe no hay multi-threading en marcha, no importa cuántas actividades o pestañas que tiene.

ContentProvider no proporciona ningún bloqueo. De hecho, puede introducir multithreading donde no lo tendría ya porque permite que otros procesos realicen llamadas en su propio proceso y cuando eso ocurre la llamada se envía desde un hilo separado en su proceso (no en la interfaz de usuario principal hilo).

Por supuesto, si usted crea sus propios hilos, entonces también tendrá multi-threading en curso.

  • GetWritableDatabase llamado recursivamente
  • ¿Qué es un buen tutorial para usar ORMLite con SQLite y Android
  • Cómo incrustar una fuente personalizada en la aplicación de Android (WebView)
  • Seleccione la última fila
  • Multi claves primarias en Android SQLite
  • Preguntas sobre el uso de Android Backup Service con una base de datos SQLite
  • Cómo almacenar datos en la base de datos sqlite con jQuery-mobile dreamviewer cc con phonegap en android?
  • Android SQLite Contraint Conflicto. El intento / captura no pudo atrapar
  • Android ContentProvider llama ráfagas de setNotificationUri () a CursorAdapter cuando se insertan muchas filas con una operación por lotes
  • Android cadena de escape real en sqlite
  • Problema de corrupción de bases de datos precargado en la aplicación de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.