SQLiteOpenHelper onCreate не создает базу данных – или она немедленно перезаписывается

У меня есть моя база данных, хранящаяся в папке моих ресурсов и скопированная во время выполнения. В настоящее время у меня есть простая операция, которая делает простой вызов базы данных:

DBAdapter adapter = new DBAdapter(HomeActivity.this); final SQLiteDatabase db = adapter.getReadableDatabase(); final Cursor c = db.query("exercises", new String[] { "name" }, null, null, null, null, null); startManagingCursor(c); if (c.moveToFirst()) Log.e(TAG, c.getString(0)); else Log.e(TAG,"No dice"); 

И ниже мой DBAdapter.java (который расширяет открытый помощник):

 public class DBAdapter extends SQLiteOpenHelper { private static final int DB_VERSION = 1; private static String DB_PATH = ""; private static final String DB_NAME = "gymrat.db"; private final Context myContext; private static final String TAG = "GymRat.DBAdapter"; /** * Constructor Takes and keeps a reference of the passed context in order to * access to the application assets and resources. * * @param context */ public DBAdapter(Context context) { super(context, DB_NAME, null, DB_VERSION); this.myContext = context; DB_PATH = "/data/data/" + context.getApplicationContext().getPackageName() + "/databases/"; } /** * Copies your database from your local assets-folder to the just created * empty database in the system folder, from where it can be accessed and * handled. This is done by transferring bytestream. * */ private void copyDatabase() throws IOException { InputStream myInput = myContext.getAssets().open(DB_NAME); String outFileName = DB_PATH + DB_NAME; OutputStream myOutput = new FileOutputStream(outFileName); byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } myOutput.flush(); myOutput.close(); myInput.close(); } /** * Call on creating data base for example for creating tables at run time */ @Override public void onCreate(SQLiteDatabase db) { Log.e(TAG, "onCreate"); try { copyDatabase(); } catch (IOException e) { Log.e(TAG,"IOException copying Database"); } } @Override public void onOpen(SQLiteDatabase db) { Log.e(TAG, "onOpen"); try { db.rawQuery("select * from exercises", null); } catch ( SQLiteException e) { Log.e(TAG,"DB copy didn't work"); try { copyDatabase(); } catch (IOException e1) { Log.e(TAG,"IOException recopying DB"); } } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.e(TAG, "Upgrading"); } } 

Я взял этот адаптер и изменил его, поскольку он не использовал функциональность OpenHelper.

Моя проблема: всякий раз, когда мое приложение запускается в первый раз после установки или после очистки данных в приложении, onCreate сначала вызывается, как и следовало ожидать, и вызывает метод copyDatabase. Проблема в том, что база данных не копируется – или если она выполняется, она сразу же перезаписывается. Вместо этого создается база данных по умолчанию с только таблицей «android meta_data», в результате чего запрос в моей активности вызывает исключение, поскольку таблица не существует.

Если я снова копирую базу данных в методе onOpen, она отлично работает. Я делаю что-то не по порядку или отсутствует какой-то вызов, вызывающий создание SQLiteOpenHelper базы данных по умолчанию? Созданная по умолчанию база данных использует то же имя и номер версии, которые указаны в конструкторе.

Прямо сейчас, как вы можете видеть, я прибегаю к использованию фиктивного запроса в onOpen, чтобы увидеть, существует ли ожидаемая таблица и если не идти вперед и не восстанавливать базу данных. Другой вариант – просто установить флаг, когда onCreate называется signaling onOpen для копирования базы данных. Очевидно, что они немного хаки, и мне очень любопытно, что происходит.

Я планирую переместить фактические вызовы базы данных на отдельные вспомогательные классы за пределами Activity, я просто вызывал db, чтобы проверить его.

Если вы хотите скопировать базу данных из активов при первом запуске и открыть базу данных из data / data / program.name / database, вы должны использовать код примерно так:

 public class YourDatabase extends SQLiteOpenHelper public YourDatabase(Context context) { super(context, DatabaseName, null, DATABASE_VERSION); this.dbContext = context; // checking database and open it if exists if (checkDataBase()) { openDataBase(); } else { try { this.getReadableDatabase(); copyDataBase(); this.close(); openDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } Toast.makeText(context, "Initial database is created", Toast.LENGTH_LONG).show(); } } 

Полный ответ, который вы можете прочитать из этого вопроса

Intereting Posts
Отображение изображений из папки с возможностью рисования с помощью универсального загрузчика изображений Не удается запустить проект cocos2dx ios в android Сколько памяти занимает каждый процесс Android? Что произойдет, когда крах активности? Android – Как сделать фоновый рисунок, объединяющий растровые изображения? Dialog.getWindow () возвращает значение null после создания диалога Андроидные медиаплееры навсегда на ICS Использование библиотеки поддержки Android 23.2 в приложении build.gradle crashes (XmlPullParserException: XmlPullParserException: недопустимый вектор ярлыка) Java Robotium Android – одновременный запуск одного и того же теста на двух разных устройствах Libgdx: SpriteBatch, флеш-шейдер на устройствах Android от Samsung работает некорректно Как я могу форматировать двойной с помощью привязки данных Android? Как просмотреть пользовательскую программную клавиатуру во время нажатия на EditText в android? Android: проверка кнопки включена Анимация анимации анимации скольжения Chrome: // проверять отображение устройства, не отображая открытые вкладки