¿La mejor manera de acceder a la base de datos en la aplicación de Android multihilo?

Use un Singletonpatrón para crear instancias SQLiteOpenHelper, por lo que en toda la aplicación debe existir una instancia de singleton. Esto asegurará que no se produzcan fugas y facilitará su vida, ya que elimina la posibilidad de olvidar cerrar su base de datos a medida que codifica. También garantizará un acceso seguro a la base de datos en toda la aplicación.

Además, no tiene que implementar su propio mecanismo de bloqueo. SQLiteDatabaseMantener el mecanismo de bloqueo. Por lo tanto, solo habrá una transacción en un momento determinado, todas las demás transacciones se realizarán Queueutilizando el Sigleton.getInstance()enfoque. Asegure un único punto de acceso a la base de datos.

Además, en este enfoque, no tiene que cerrar las conexiones de la base de datos, ya que SQLiteDatabase lanzará todas las referencias una vez que se haya realizado la transacción. Por CustomSQLiteHelper.getInstance()lo tanto, debe usarse siempre que desee realizar operaciones CRUD y eliminar el bloqueo de mecansim.

Más información, visite el blog http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html y vea los comentarios también.

Espero que esto ayude.

Respuesta 1

Definitivamente recomendaría que envuelva su base de datos en un ContentProvider.

Proporciona buenas características de fábrica y desplaza muchas tareas potencialmente complicadas al marco. No necesitará tratar con ayudantes de base de datos singleton, porque tiene la garantía de que tiene una única ContentResolverinstancia para su aplicación que reenviará comandos al proveedor deseado.

Puede utilizar todo el Loadermarco y las clases de ayuda agradables, como AsyncQueryHandlertratar con algunas de las advertencias más comunes del acceso a la base de datos.

Aconsejaría no sincronizar el acceso a sus métodos CRUD. Como se menciona en la documentación y en las respuestas anteriores, la base de datos debe ocuparse de esto. Sin mencionar la posible penalización de rendimiento en una aplicación que requiere un uso intensivo de la base de datos.

Nota al margen: como primer paso, puede ser útil si intenta determinar qué causa estos accidentes, ¿son esporádicos? Un ejemplo más concreto puede resultar útil al solucionar problemas.

Respuesta: 2

Puede usar los proveedores de contenido.

Respuesta: 3

Creo que usar un bloqueo de lectura-escritura es suficiente en la mayoría de los casos. Mira esta respuesta. La solución no usa ContentProvider. En cambio, usa la ReentrantReadWriteLockclase en el java.util.concurrent.lockspaquete.

Respuesta: 4

Además de asegurarse de que SQLiteOpenHelper sea un singleton, debe habilitar el registro de escritura anticipada si desea que varios subprocesos accedan a la base de datos:

https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging ()

Hacer esto solucionó el problema para mí.

Respuesta: 5

Como se discutió en los comentarios, no habrá Bloqueo de bloqueo si usa una instancia de DB. Así que dudo de DeadLock porque estás usando la transacción.

un tipo de ejemplo de DeadLock es:

  1. en una transacción:

    actualizar la tabla A -> actualizar la tabla B -> commit

  2. en otra transacción:

    actualizar la tabla B -> actualizar la tabla A -> confirmar

así que en el medio tiempo, 1 espera 2 y 2 espera 1 al mismo tiempo, entonces ocurre Deadlock.

Si realmente es un punto muerto, puede corregir la consulta para que esto no suceda o puede usar la consulta en cola (o consulta asíncrona) como Actor.

por ejemplo, la biblioteca commons-dbutils tiene soporte para un AsyncQueryRunner al que le proporciona un ExecutorService y devuelve un futuro. (de: ¿Es posible la llamada asíncrona jdbc?)

Respuesta: 6

Lo que estoy tratando de hacer es sacar un par de padres poms para todos nuestros subproyectos. Tengo un solo proyecto que contiene un pom padre único con dos poms de módulo hijo. Embalaje para los tres ...

Necesito (principalmente para fines de prueba) escribir un consumidor cuyo propósito sea recordar cuántas veces se llamó. Sin embargo, no puedo hacer int i = 0; <Object> handler del consumidor = o -> i ++ ...

Como se indica en el título, me pregunto si es necesario generar el envío * .jar. Estoy usando Datastax Enterprise Cassandra por un tiempo, pero ahora también necesito usar Spark. Vi casi todos los videos de DS320: ...

Estoy recibiendo un mensaje SOAP sobre un servlet java con una parte adjunta que contiene un mimo multiparte. Haciendo esto: InputStream inputStream = request.getInputStream (); byte [] datos = IOUtils ....