Это была проблема для меня, когда я только начинал с Android, так как в Интернете не так много учебников, в которых описывается, как правильно разрешить доступ к вашей базе данных во всем приложении (не спрашивайте меня, почему). Вот пример кода, который демонстрирует три возможных подхода.
Подход № 1: создание подклассов `Application`
Если вы знаете, что ваше приложение не будет очень сложным (т. Е. Если вы знаете, что в конечном итоге у вас будет только один подкласс Application
), то вы можете создать подкласс Application
и расширить основное действие. Это. Это гарантирует, что один экземпляр базы данных работает на протяжении всего жизненного цикла приложения.
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;
}
}
Подход №2: иметь `SQLiteOpenHelper` в качестве статического члена данных
Это не полная реализация, но она должна дать вам хорошее представление о том, как правильно проектировать класс DatabaseHelper
. Метод статической фабрики гарантирует, что в любой момент времени существует только один экземпляр DatabaseHelper.
/**
* 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;
}
}
Подход № 3: абстракция базы данных SQLite с помощью `ContentProvider`
Это подход, который я бы предложил. С одной стороны, новый класс LoaderManager
в значительной степени зависит от ContentProviders, поэтому, если вы хотите, чтобы Activity или Fragment реализовали LoaderManager.LoaderCallbacks<Cursor>
(что я предлагаю вам использовать в своих интересах, это волшебно!), Вам нужно реализовать ContentProvider
для вашего приложения. Кроме того, вам не нужно беспокоиться о создании помощника базы данных Singleton с помощью ContentProviders. Просто позвоните getContentResolver()
из Упражнения, и система позаботится обо всем за вас (другими словами, нет необходимости разрабатывать шаблон Singleton для предотвращения создания нескольких экземпляров).
Надеюсь, это поможет!