una tutorial studio para hacer example español ejemplo datos con como aplicaciones sqlite android-sqlite

tutorial - ¿Cuándo se llama al método onCreate SQLiteOpenHelper?



sqliteopenhelper android studio (4)

Intenté crear una base de datos SQLite y hacer algunas cosas con ella. ¡¡Pero encontré que mi método onCreate ni siquiera es invocado !!

Estoy enviando un mensaje a LogCat al principio del método onCreate .

Mi suposición es que el (super) constructor invocará el método onCreate . ¿Está bien?

Mi código:

import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase; import android.content.Context; import android.database.Cursor; import android.content.ContentValues; import android.util.Log; public class DatabaseHandler extends SQLiteOpenHelper { // Static Constants /*** Database details ***/ // Database version private static final int DATABASE_VERSION = 1; // Database name private static final String DATABASE_NAME = "database_name"; /*** Database Tables ***/ /** Events **/ // Event table private static final String TABLE_EVENT = "event"; // Event table columns private static final String COLUMN_EVENT_EID = "_eid"; private static final String COLUMN_EVENT_CREATION_DATE = "creation_date"; private static final String COLUMN_EVENT_TITLE = "title"; private static final String COLUMN_EVENT_ICON = "icon"; public DatabaseHandler(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { Log.e("MyApp", "onCreate invoked"); // Tables creation queries String CREATE_EVENT_TABLE = "create table " + TABLE_EVENT + "(" + COLUMN_EVENT_EID + " integer primary key, " + COLUMN_EVENT_CREATION_DATE + " text, " + COLUMN_EVENT_TITLE + " text, " + COLUMN_EVENT_ICON + " text)"; // Creating tables db.execSQL(CREATE_EVENT_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.e("MyApp", "onUpgrade invoked"); db.execSQL("DROP TABLE IF EXISTS " + TABLE_EVENT); } }

Código de actividad principal:

import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DatabaseHandler db = new DatabaseHandler(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }


Como dicen los documentos oficiales, " getWritableDatabase () Crea y / o abre una base de datos que se usará para leer y escribir. La primera vez que se llame, la base de datos se abrirá y se creará en (SQLiteDatabase), en Upgrade (SQLiteDatabase, int, se llamará int) y / o onOpen (SQLiteDatabase) ".

Una vez que se abre con éxito, la base de datos se almacena en caché, por lo que puede llamar a este método cada vez que necesite escribir en la base de datos. (Asegúrese de llamar a close () cuando ya no necesite la base de datos). Los errores, como los permisos incorrectos o un disco lleno, pueden hacer que falle este método, pero los intentos futuros pueden tener éxito si se soluciona el problema.

http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#getWritableDatabase()


Déjame aclarar el flujo lógico. Aquí está el concepto de inicialización perezosa .

El (super) constructor en DatabaseHandler no invocará el método onCreate . El constructor de DatabaseHandler llamante se inicializará: contexto, nombre de la base de datos, fábrica que crea la base de datos, versión de la base de datos y controlador de errores de la base de datos.

getWritableDatabase () > getDatabaseLocked () > - SQLiteDatabase.create ()

O

getReadableDatabase () > getDatabaseLocked () > - SQLiteDatabase.create ()

Respuesta: Una vez que su base de datos se haya creado con éxito, sus configuraciones cambiarán, la próxima vez que getReadableDatabase() o getWritableDatabase() llame a getDatabaseLocked() y se onCreate(db) método onCreate(db) dentro de getDatabaseLocked() .

Explicación:

El SQLiteDatabase.create() anterior SQLiteDatabase.create() es responsable de crear SQLiteDatabase en el disco.

Pero el proceso en inicialización perezosa (es decir, no hace que todo esté listo. Crea esos objetos en el tiempo de ejecución si los necesita. Para esto se usaron muchas declaraciones if..else de lo if..else ).

Si ves el cuerpo completo de getDatabaseLocked() , esto está abajo. [ Puedes buscar el método onCreate() dentro del cuerpo de getDatabaseLocked() ]

private SQLiteDatabase getDatabaseLocked(boolean writable) { if (mDatabase != null) { if (!mDatabase.isOpen()) { // Darn! The user closed the database by calling mDatabase.close(). mDatabase = null; } else if (!writable || !mDatabase.isReadOnly()) { // The database is already open for business. return mDatabase; } } if (mIsInitializing) { throw new IllegalStateException("getDatabase called recursively"); } SQLiteDatabase db = mDatabase; try { mIsInitializing = true; if (db != null) { if (writable && db.isReadOnly()) { db.reopenReadWrite(); } } else if (mName == null) { db = SQLiteDatabase.create(null); } else { try { if (DEBUG_STRICT_READONLY && !writable) { final String path = mContext.getDatabasePath(mName).getPath(); db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY, mErrorHandler); } else { db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ? Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0, mFactory, mErrorHandler); } } catch (SQLiteException ex) { if (writable) { throw ex; } Log.e(TAG, "Couldn''t open " + mName + " for writing (will try read-only):", ex); final String path = mContext.getDatabasePath(mName).getPath(); db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY, mErrorHandler); } } onConfigure(db); final int version = db.getVersion(); if (version != mNewVersion) { if (db.isReadOnly()) { throw new SQLiteException("Can''t upgrade read-only database from version " + db.getVersion() + " to " + mNewVersion + ": " + mName); } db.beginTransaction(); try { if (version == 0) { onCreate(db); } else { if (version > mNewVersion) { onDowngrade(db, version, mNewVersion); } else { onUpgrade(db, version, mNewVersion); } } db.setVersion(mNewVersion); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } onOpen(db); if (db.isReadOnly()) { Log.w(TAG, "Opened " + mName + " in read-only mode"); } mDatabase = db; return db; } finally { mIsInitializing = false; if (db != null && db != mDatabase) { db.close(); } } }

Tenga en cuenta que , dentro del cuerpo del método getDatabaseLocked() , hay muchos casos, si no ... Estos casos de if .. else determinan su entorno actual (configuración) y, en función de su entorno actual, utilizan los métodos adecuados para iniciar / configurar lo que sea necesario.

Además, tenga en cuenta: todos los métodos de devolución de llamada en su DatabaseHandler (clase que implementó SQLiteOpenHelper ) se llaman dentro del cuerpo getDatabaseLocked() .

Código fuente SQLiteOpenHelper.java : https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/database/sqlite/SQLiteOpenHelper.java

Código fuente SQLiteDatabase.java : https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/database/sqlite/SQLiteDatabase.java

Ejemplo a seguir: https://github.com/uddhavgautam/SQLiteBasicSample



Tienes razón, el (super) constructor invocará el método onCreate, PERO solo si la base de datos real no existe. De http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onCreate%28android.database.sqlite.SQLiteDatabase%29

Una clase auxiliar para administrar la creación de bases de datos y la administración de versiones.

Usted crea una subclase implementando onCreate (SQLiteDatabase), onUpgrade (SQLiteDatabase, int, int) y opcionalmente onOpen (SQLiteDatabase), y esta clase se encarga de abrir la base de datos si existe, la crea si no existe y la actualiza según sea necesario. .