44

プロジェクトで Android 互換性ライブラリを使用しています。DevGuide ( http://developer.android.com/reference/android/app/Fragment.html ) で説明されているように ListFragment をセットアップし、単純な CursorLoader Christian を使用して、コンテンツ プロバイダーなしで使用できるようにしました ( ContentProvider を使用しない CursorLoader の使用)。

問題は、ListFragment / 親アクティビティのどこで、データベースを開き、カーソルを返し、アダプターを作成し、ListAdapter を設定する必要があるかということです。

したがって、私のアプリには、TitlesFragment、DetailsFragment、FragmentLayoutActivity、DetailsLayoutActivity があります。

ベストプラクティスですか...

  • 以下のコードサンプルonActivityCreatedのように、ListFragment でデータベースを開き、ListFragment でデータベースを閉じます。onDestroy

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Open database
        playersDatabaseHelper = new PlayersDBAdapter(getActivity());
        playersDatabaseHelper.open();
        getLoaderManager().initLoader(0, null, this);
        ...
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (playersDatabaseHelper != null) {
            playersDatabaseHelper.close();
        }
    }
    
  • 以下のサンプル コードのように、データベースにクエリを実行してカーソルを返し、onCreateLoaderアダプタと setListAdapter を作成します。onLoadFinished

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // Now create and return a CursorLoader that will take care of
        // creating a Cursor for the data being displayed.
        return new MyCursorLoader(getActivity()) {
            @Override
            public Cursor loadInBackground() {
                playersCursor = playersDatabaseHelper.getAllPlayers();
                return playersCursor;
            }
        };
    
    }
    
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {      
        // Create an empty adapter we will use to display the loaded data.
        playersAdapter = new RowAdapter(getActivity(), playersCursor, R.layout.players_overview_row);
    
        // Allocate the adapter to the List displayed within this fragment.
        setListAdapter(playersAdapter);
    
        playersAdapter.swapCursor(cursor);
    
        // The list should now be shown.
        if (isResumed()) {
            setListShown(true);
        } else {
            setListShownNoAnimation(true);
        }
    }
    

私は正しい軌道に乗っていますか、それともそれらのいくつかをどこかに移動する必要がありますか? 御時間ありがとうございます!

4

1 に答える 1

6

CursorLoader と Fragment の経験はまだありませんが、さまざまなスレッドとアクティビティによる同時アクセスのコンテキストで SQLiteOpenHelper を使用した経験があります。

PlayersDBAdapter は内部で SQLiteOpenHelper クラスを使用していると仮定します。しかし、あなたのメソッド open() と close() が何をしているのか明確ではありませんか?

私がしたこと:

  • SQLiteOpenHelper を、アクティビティ全体ではなく、アプリケーション全体のシングルトンとして定義します
  • アプリケーションonCreateでSQLiteOpenHelper単一インスタンスをインスタンス化します
  • アクティビティ onDestroy で SQLiteOpenHelper インスタンスを解放しないでください。アクティビティが停止すると、別のアクティビティがまだ DB を開く必要がある場合があります。
  • SQLiteOpenHelper インスタンスは、アプリケーション onTerminate でクリアする必要があると思います (onTerminate が実際に呼び出されることはほとんどないため、わかりません)。
  • mySQLiteOpenHelper.getWritableDatabase() で SQLiteDatabase 参照を取得する DBAdapter オブジェクトがあります。
  • これらの DBAdapter は通常、アクティビティ onCreate で割り当てられ、onDestroy で解放されます

少なくともこれは機能し、数千のユーザーがいるアプリケーションではクラッシュしません。それを改善するための提案は大歓迎です:-)

于 2011-12-06T17:21:51.063 に答える