Скорее всего вы уже находили множество примеров создания собственной базы данных, которые являются копированием друг-друга и преимущественное большинство которых просто не обновляются. Потому я решил выложить пример использование заранее созданной БД, с простой реализацией обновления данных.
Действительно, при поиске действительно рабочего примера я не нашёл ничего, все примеры найденные мною были практически одинаковые и несомненно работали, но когда возникла необходимость обновить базу данных с новой версией приложения - не произошло абсолютно ничего.
Почему не работает обычный способ.
В примерах которые можно найти в интернете в большем обилии, при обращении к вашей БД, приходится вызывать её с помощью метода createDatabase(), которая копирует вашу заранее созданную базу в папку приложения. Но при вызове данного метода Android не обращается к методу onUpdate() , потому даже если вы измените версию базы, ничего не произойдёт, так как не произойдёт сравнение её версий.
Метод onUpdate() вызывается только в случае обращения к базе данных с помощью методов getWritableDatabase() или getReadableDatabase(), в этом случае база создается и копируется если не существовала ранее и вызывается метод onUpdate(),если база уже существовала. Но если вы попробуете в методе onUpdate() удалить прошлую версию БД - приложение закроется с крешем, так как метод обновления будет вызван (а значит и база будет удалена) раньше чем будет создана новая, а потому получить доступ к несуществующей в этот момент базе не удастся.
Как обновить собственную базу данных.
Для того, чтобы удалить старую и обновить БД придется вручную контролировать её версию и сделать это до вызова метода onUpdate(), чтобы избежать попытки её открытия до её фактического создания. Для этого будем использовать собственный метод обновления, а версии хранить и контролировать с помощью SharedPreferences.
Для использования собственной базы данных в Android создайте новый класс ExternalDbOpenHelper и поместите в него приведённый ниже код.
import android.content.Context; import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.preference.PreferenceManager; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Created by AwesomeDevelop on 24.12.2014. */ public class ExternalDbOpenHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "db.sqlite3"; // Название файла с БД private static final int DATABASE_VERSION = 1; //Версия БД private static final String SP_KEY_DB_VER = "db_ver"; private final Context mContext; public ExternalDbOpenHelper(Context context, String DB_NAME) { super(context, DATABASE_NAME, null, DATABASE_VERSION); mContext = context; initialize(); } /** * Инициализация БД. Создание новой если ранее не существовала. */ private void initialize() { if (databaseExists()) { SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(mContext); int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1); if (DATABASE_VERSION != dbVersion) { File dbFile = mContext.getDatabasePath(DATABASE_NAME); if (!dbFile.delete()) { // Log.w(TAG, "Невозможно обновить БД"); } } } if (!databaseExists()) { createDatabase(); } } /** * Проверка существования файла БД. Если существует - возвращает true. * @return */ private boolean databaseExists() { File dbFile = mContext.getDatabasePath(DATABASE_NAME); return dbFile.exists(); } /** * Создание БД, копирование файла из Assets. */ private void createDatabase() { String parentPath = mContext.getDatabasePath(DATABASE_NAME).getParent(); String path = mContext.getDatabasePath(DATABASE_NAME).getPath(); File file = new File(parentPath); if (!file.exists()) { if (!file.mkdir()) { // Log.w(TAG, "Невозможно создать папку БД"); return; } } InputStream is = null; OutputStream os = null; try { is = mContext.getAssets().open(DATABASE_NAME); os = new FileOutputStream(path); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } os.flush(); SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(mContext); SharedPreferences.Editor editor = prefs.edit(); editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION); editor.commit(); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
Для работы данного класса, вам необходимо только указать название файла с созданной вами базой данных и её версию. Как только версия БД будет увеличена - старая её версия будет удалена, а новый файл БД скопирован. Но не пробуйте понизить версию, как и при обычном использовании будет получена ошибка о невозможности выполнить DownGrade и приложение будет закрыто.
Работа с БД осуществляется стандартными для Android способами, потому вы можете работать с ней, как с стандартной Sqlite базой.
Открытие БД.
ExternalDbOpenHelper dbOpenHelper = new ExternalDbOpenHelper(this, DB_NAME); SQLiteDatabase database= dbOpenHelper.getWritableDatabase();Получить данные можно, к примеру, вот так:
data = new ArrayList(); Cursor dataCursor = database.query( TABLE_NAME, new String[] { DATA_NAME,DATA_IMAGE}, null, null, null, null, DATA_NAME); dataCursor.moveToFirst(); if(!dataCursor.isAfterLast()){ do { String image =dataCursor.getString(1); String name = dataCursor.getString(0); data.add(new BrandData(name,image)); } while (dataCursor.moveToNext()); } dataCursor.close();
И так, для использование заранее созданной базы данных необходимо:
- Создать файл базы данных Sqlite с любым наполнением, о том как это сделать можно прочитать тут, а для создания использовать Navicat .
- Поместить созданный файл в папку Assets.
- Создать класс ExternalDbOpenHelper и поместить в него код, приведённый в статье.
- Использовать вашу БД стандартными способами, описанными в официальной документации.
Комментариев нет:
Отправить комментарий