База данных глобального экземпляра - PullRequest
6 голосов
/ 02 сентября 2011

Итак, я хочу иметь один экземпляр базы данных для всех операций приложения.Я нашел следующий код:

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;
    }
}

Я не понимаю, когда я могу закрыть экземпляр SQLiteDatabase.

Ответы [ 3 ]

13 голосов
/ 15 февраля 2012

Это была проблема для меня, когда я только начинал с 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 для предотвращения создания нескольких экземпляров).

Надеюсь, это поможет!

2 голосов
/ 02 сентября 2011

Вам действительно не нужно закрывать его. Он будет автоматически закрыт, когда ваш процесс умрет. Вместо того чтобы использовать объект Application, вы можете просто сделать объект-помощник DB одноэлементным для более легкого доступа. Кстати, getWritableDatabase() и getReadableDatabase() ничем не отличаются. Единственная разница в том, что getReadableDatabase() может работать, если у вас недостаточно места, в то время как другой вызовет исключение.

0 голосов
/ 02 сентября 2011

Я не думаю, что это рекомендуется, если у вас есть глобальный экземпляр DataBaseOpenHelper, и вызывайте getWritableDatabase () в тех точках, где вам действительно нужна БД. И, очевидно, получайте доступный для записи экземпляр только тогда, когда вам это нужно, в противном случае используйте getReadableDatabase ().

Я не уверен, что именно причина этого, но я предполагаю, что это дорогой объект, чтобы получить и / или удерживать его, поэтому вы не хотите создавать его, когда приложение загружается и удерживается глобальный экземпляр. Может быть, кто-то еще может прояснить этот момент. Я бы хотел, чтобы в документации для Android это было лучше объяснено, потому что у меня тоже был импульс сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...