Instancia global de base de datos

Así que quiero tener una instancia de base de datos para todas las actividades de la aplicación. Encontré el código siguiente:

public class MyApplication extends Application { private static SQLiteDatabase mDB = null; @Override public void onCreate() { super.onCreate(); DataBaseOpenHelper m_OpenHelper = new DataBaseOpenHelper( this ); mDB = m_OpenHelper.getWritableDatabase(); } public static SQLiteDatabase getDB() { return mDB; } } 

No entiendo cuando puedo cerrar la instancia de SQLiteDatabase.

Esto fue un problema para mí cuando empecé con Android, ya que no hay muchos tutoriales en la web que describen cómo permitir correctamente el acceso a su base de datos en toda la aplicación (no me pregunte por qué). He aquí un ejemplo de código que muestra tres posibles enfoques.

Enfoque # 1: subclasificación `Application`

Si sabe que su aplicación no será muy complicada (es decir, si sabe que sólo terminará teniendo una subclase de Application ), entonces puede crear una subclase de Application y hacer que su Actividad principal la extienda. Esto garantiza que se ejecute una instancia de la base de datos durante todo el ciclo de vida de la aplicación.

 public class MainApplication extends Application { /** * see NotePad tutorial for an example implementation of DataDbAdapter */ private static DataDbAdapter mDbHelper; /** * create the database helper when the application is launched */ @Override public void onCreate() { mDbHelper = new DataDbAdapter(this); mDbHelper.open(); } /** * close the database helper when the application terminates. */ @Override public void onTerminate() { mDbHelper.close(); mDbHelper = null; } public static DataDbAdapter getDatabaseHelper() { return mDbHelper; } } 

Enfoque # 2: tiene `SQLiteOpenHelper` ser un miembro de datos estáticos

Esta no es la implementación completa, pero debería darle una buena idea sobre cómo diseñar la clase DatabaseHelper correctamente. El método estático de fábrica garantiza que sólo existe una instancia de DatabaseHelper en cualquier momento.

 /** * create custom DatabaseHelper class that extends SQLiteOpenHelper */ public class DatabaseHelper extends SQLiteOpenHelper { private static DatabaseHelper mInstance = null; private static final String DATABASE_NAME = "databaseName"; private static final String DATABASE_TABLE = "tableName"; private static final int DATABASE_VERSION = 1; private Context mCxt; public static DatabaseHelper getInstance(Context ctx) { /** * use the application context as suggested by CommonsWare. * this will ensure that you dont accidentally leak an Activitys * context (see this article for more information: * http://developer.android.com/resources/articles/avoiding-memory-leaks.html) */ if (mInstance == null) { mInstance = new DatabaseHelper(ctx.getApplicationContext()); } return mInstance; } /** * constructor should be private to prevent direct instantiation. * make call to static factory method "getInstance()" instead. */ private DatabaseHelper(Context ctx) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.mCtx = ctx; } } 

Enfoque # 3: abstraer la base de datos SQLite con un `ContentProvider`

Este es el enfoque que yo sugeriría. Por un lado, la nueva clase LoaderManager depende en gran medida de ContentProviders, así que si quieres que una Actividad o Fragmento implemente LoaderManager.LoaderCallbacks<Cursor> (que te sugiero que aproveches, es mágico!), Tendrás que implementar un ContentProvider para su aplicación. Además, no necesita preocuparse por crear un ayudante de base de datos Singleton con ContentProviders. Simplemente llame a getContentResolver() de la Actividad y el sistema se encargará de todo para usted (en otras palabras, no hay necesidad de diseñar un patrón Singleton para evitar que se creen varias instancias).

¡Espero que ayude!

Usted realmente no necesita cerrarlo. Se cerrará automáticamente cuando el proceso muera. En lugar de utilizar el objeto de aplicación, sólo puede hacer que su objeto de ayuda de DB un singleton para facilitar el acceso. BTW, getWritableDatabase() y getReadableDatabase() no son tan diferentes. La única diferencia es que getReadableDatabase() podría funcionar si está fuera de espacio, mientras que el otro lanzará una excepción.

No creo que esto se recomienda, si algo que podría tener una instancia global de DataBaseOpenHelper, y llamar a getWritableDatabase () en los puntos donde realmente necesita la base de datos. Y, obviamente, sólo obtener la instancia de escritura cuando lo necesite, de lo contrario, use getReadableDatabase ().

No estoy seguro de exactamente la razón detrás de esto, pero mi conjetura es que este es un objeto caro para obtener y / o celebrar, por lo que no desea crearlo cuando la aplicación se carga y se aferran a una instancia global . Tal vez alguien más puede aclarar este punto. Ojalá los documentos Android explicaría esto mejor porque también tuve el impulso de hacer esto.

  • SQLiteException: no se puede iniciar una transacción dentro de una transacción (código 1)
  • Cómo escribir la prueba de Robolectric (2.3) usando la base de datos
  • Base de datos en el estudio android
  • ¿Podemos usar una base de datos SQLITE aldready preparada para una aplicación phonegap?
  • Permitir sólo la entrada de datos únicos con Android SQLite?
  • ¿Por qué los Cursores Android comienzan antes de la primera fila de resultados y terminan después de la última fila?
  • Se filtró un objeto SQLiteConnection para la base de datos. Por favor, corrija su aplicación
  • Excepción "tabla ... no tiene columna nombrada ..."
  • ¿Es seguro almacenar nombre de usuario y contraseñas en un SQLite local db en Android?
  • ¿Qué tipos de caché realiza SQLite en Android?
  • Ormlite Android inserciones masivas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.