Почему DBHelper не закрыт в учебнике по Android-блокноту? - PullRequest
1 голос
/ 03 апреля 2012

В настоящее время я пишу свое первое приложение для Android и основал большую часть своих знаний на учебнике по Android-блокноту:

http://developer.android.com/resources/tutorials/notepad/notepad-ex3.html

В моем приложении я использую несколько DBHelpers в одном действии, и не каждый Курсор управляется действием с помощью startManagingCursor ().

Я узнал, что каждое соединение с БД должно быть открыто и закрыто:

SQLiteOpenHelper.open();
Cursor.open();
//use cursor
Cursor.close();
SQLiteOpenHelper.close();

Насколько я знаю, startManagingCursor () делает эту работу за вас. Но startManagingCursor () также открывает и закрывает SQLiteOpenHelper?

В учебнике по Android Notepad используется startManagingCursor (), но DBHelper никогда не закрывается. Почему SQLiteOpenHelper никогда не закрывается?

EDIT:

Это мой текущий код. Он использует один SQLiteOpenHelper с именем mDriverDbHelper. Этот код взят из учебного пособия:

частный DriverDbAdapter mDriverDbHelper;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.bus_selectuser);
    mDbHelper = new DbAdapter(this);
    mDbHelper.open();
    mDbHelper.close();
    mDriverDbHelper = new DriverDbAdapter(this);
    Log.w("BuerBusActivity", "opening DB connection via DbHelber now");

    mDriverDbHelper.open();
    fillData();

    //request the screen to stay on
    this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

@Override
public void onRestart() {
    super.onRestart();

    Log.v(TAG, "onRestart");
}

@Override
public void onStart() {
    super.onStart();
    mDriverDbHelper.open();
    Log.v(TAG, "onStart");
}

@Override
public void onResume() {
    super.onResume();
    Log.v(TAG, "onResume");
}

@Override
public void onPause() {
    Log.v(TAG, "onPause");
    super.onPause();
}

@Override
public void onStop() {
    mDriverDbHelper.close();
    Log.v(TAG, "onStop");
    super.onStop();
}

Этот пример кода работает, но я не понимаю, почему. Я вызываю mDriverDBHelper.open () дважды в onCreate и в onStart.

Я пытался поместить вызовы open () и close () в onPause и onResume, но это приводит к ошибке:

Cursor: invalid statement in fillWindow()

Кто-нибудь знает, почему это должно быть onStart и onStop, а не onPause и onResume?

ФИНАЛЬНЫЙ ОТВЕТ

В учебнике отсутствует вызов метода close (). Общее правило использования открытия и закрытия в сочетании с жизненным циклом деятельности:

После открытия SQLiteOpenHelper в методе жизненного цикла действия вы должны закрыть его в соответствующем методе жизненного цикла аналога.

@Override
public void onCreate() {
    ....
    //open SQLiteOpenHelper
    onCreateHelper.open();
}

@Override
public void onStart() {
    ....
    //open SQLiteOpenHelper
    onStartHelper.open();
}

@Override
public void onResume() {
    ....
    //open SQLiteOpenHelper
    onResumeHelper.open();
}

@Override
public void onPause() {
    ....
    //close SQLiteOpenHelper
    onResumeHelper.close();
}

@Override
public void onStop() {
    ....
    //close SQLiteOpenHelper
    onStartHelper.close();
}

@Override
public void onDestroy() {
    ....
    //close SQLiteOpenHelper
    onCreateHelper.close();
}

В случае учебника по Android NotePad метод onDestroy () отсутствовал и должен был закрыть mDbHelper.

Ответы [ 3 ]

2 голосов
/ 03 апреля 2012

Согласно документации startManagingCursor, он обрабатывает только курсоры. Поэтому я считаю, что это ничего не делает с подключением к базе данных, поскольку в будущем может потребоваться повторный запрос данных.

С сайта разработчика Android:

Этот метод позволяет деятельности позаботиться об управлении данным Жизненный цикл курсора для вас основан на жизненном цикле действия. То есть, когда действие останавливается, оно автоматически вызывает deactivate () на данный курсор, и когда он будет перезапущен позже, он будет вызывать Requery () для вас. Когда действие уничтожено, все управляемые курсоры будет закрыто автоматически.

Что касается закрытия соединения с базой данных в учебнике по Android Notepad, я думаю, что они пропустили его закрытие в своем примере кода. Так что ничего страшного:)

0 голосов
/ 24 июля 2013

Никогда не закрывайте DbHelper предназначен для того, чтобы оставаться открытым вечно.

И не закрывайте результаты getReadableDatabase () и getWritableDatabase (), даже если это один и тот же объект в оптимальных условиях.

Проверьте исходный код, даже программисту это не понравится:

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

А для стабильности и ускорения транзакций использования, проверьте это: http://tech.vg.no/2011/04/04/speeding-up-sqlite-insert-operations/

0 голосов
/ 05 марта 2013

Несмотря на это, пример кода также не учитывает реальную возможность того, что пользователь нажмет кнопку устройства назад . Это, вероятно, приведет к тому, что нулевые указатели будут переданы через дополнительные функции пакета. Чтобы избежать сбоя примера, вы можете просто обернуть блок try / catch вокруг всего после супер-вызова, например:

 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
        try {
              Bundle extras = intent.getExtras();

              switch(requestCode) {
              case ACTIVITY_CREATE:
                     String title = extras.getString(NotesDbAdapter.KEY_TITLE);  
                              // ^^^ LATER down goes KA-BOOM !
               // etc ... as in sample
              } // end switch stmt
         } catch (Exception e ) {
          Log.d ( "onActivityResult caught exception: ", e.toString() ) ;
         } // end try / catch
    // ...   

Как и в C / C ++, похоже null Материал - самая распространенная ошибка в Java ...

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