1

私は現在、最初のAndroidアプリを作成しており、ほとんどの知識はAndroidのメモ帳のチュートリアルに基づいています。

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

私のアプリケーションでは、1つのアクティビティで複数のDBHelperを使用していますが、すべてのカーソルがstartManagingCursor()を使用してアクティビティによって管理されるわけではありません。

私は、すべてのDB接続を適切に開いたり閉じたりする必要があることを学びました。

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

私の知る限り、startManagingCursor()はあなたのためにこれを行います。しかし、startManagingCursor()もSQLiteOpenHelperを開いたり閉じたりしますか?

Android NotepadチュートリアルはstartManagingCursor()を使用していますが、DBHelperが閉じられることはありません。SQLiteOpenHelperが閉じられないのはなぜですか?

編集:

これは私の現在のコードです。mDriverDbHelperと呼ばれる1つのSQLiteOpenHelperを使用しています。このコードは、チュートリアルからの採用です。

プライベートDriverDbAdaptermDriverDbHelper;

/** 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();
}

このコードサンプルは機能しますが、理由がわかりません。onCreateとonStartでmDriverDBHelper.open()を2回呼び出しています。

open()およびclose()呼び出しをonPauseおよびonResumeに入れようとしましたが、エラーが発生します。

Cursor: invalid statement in fillWindow()

onPauseとonResumeではなくonStartとonStopでなければならない理由を誰かが知っていますか?

最終回答

チュートリアルにはclose()メソッド呼び出しがありません。アクティビティのライフサイクルと組み合わせてオープンとクローズを使用するための一般的なルールは次のとおりです。

アクティビティのライフサイクルメソッドでSQLiteOpenHelperを開いた後、対応する対応するライフサイクルメソッドで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を閉じる必要があります。

4

3 に答える 3

2

ドキュメントによるstartManagingCursorと、カーソルのみを処理します。したがって、将来データの再クエリが必要になる可能性があるため、データベース接続では何もしないと思います。

Android 開発者のサイトから:

このメソッドにより、アクティビティは、アクティビティのライフサイクルに基づいて、指定された Cursor のライフサイクルを管理できます。つまり、アクティビティが停止すると 、指定された Cursor で自動的に activate() が呼び出され、後で再開されると requery() が呼び出さ ます。アクティビティが破棄されると、管理されているすべての Cursor が自動的に閉じられます。

Androidメモ帳のチュートリアルでのデータベース接続のクローズについて、サンプルコードでクローズするのを忘れていたと思います。だから大したことはありません:)

于 2012-04-03T15:25:09.250 に答える
0

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/

于 2013-07-24T02:21:15.263 に答える
0

価値があるのは、サンプル コードでは、ユーザーがデバイスの戻るボタンを押す可能性についても扱っていないことです。これにより、null ポインターがバンドル エクストラを介して渡される可能性があります。サンプルがクラッシュしないようにするには、次のように、スーパー コールの後にすべてを 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++ のように、Java で最も一般的なエラーはnullのようです ...

于 2013-03-05T03:34:18.760 に答える