25

私は自分のアプリで広範囲に使用Cursorsして、データベースから情報を読み込んだり、データベースに情報を書き込んだりします。Honeycomb と Compatibility PackageLoaderには、「適切な」方法でデータをロードするのに役立つように設計された新しいクラスがあることがわかりました。

基本的に、これらの新しいクラス (特にCursorLoader) は、以前のデータ管理方法よりもかなり優れていますか? たとえば、CursorLoader過剰管理の利点は何ですか?Cursors

そしてContentProvider、データを処理するために a を使用しますが、これは明らかにかかりますが、これはどのようにメソッドUrisと噛み合うのでしょうか? ローダーを個別に使用するinitLoader()には、それぞれをセットアップする必要がありますか? Fragmentsまた、ID は各ローダーに対してどの程度一意である必要がありますか?それはアプリの範囲を超えているのでしょうか?それとも単なるフラグメントでしょうか? UriCursorLoader に a を渡してデータをクエリする簡単な方法はありますか?

現時点でわかるのは、ローダーがデータをアプリに取り込むために不要な余分なステップを追加することだけです。

4

2 に答える 2

44

CursorLoaderアプリで を よりも使用することには、次の 2 つの主な利点がありActivity.managedQuery()ます。

  1. クエリはバックグラウンド スレッドで処理されるため (ビルドされているためAsyncTaskLoader)、大規模なデータ クエリによって UI がブロックされることはありません。これは、プレーンを使用するときにドキュメントで推奨されていることですCursorが、現在は内部で行われています。
  2. CursorLoader自動更新中です。は、最初のクエリを実行するだけでなく、要求したデータセットに をCursorLoader登録し、データ セットが変更されたときに自身を呼び出します。これにより、ビューを更新するためにデータが変更されるたびに非同期コールバックが発生します。ContentObserverforceLoad()

Loaderインスタンスは単数形LoaderManagerでも処理されるため、カーソルを直接管理する必要はなく、単一の を超えても接続を維持できるようになりましたActivityLoaderManager.initLoader()また、クエリ用に既に設定されLoaderManager.restartLoader()ている既存のデータに再接続でき、Loader場合によっては、最新のデータが利用可能な場合は即座に取得できます。

あなたのActivityまたはFragmentおそらく今LoaderManager.Callbackインターフェースを実装します。を呼び出すinitLoader()onCreateLoader()、クエリを作成するメソッドと、必要に応じて新しいCursorLoaderインスタンスが作成されます。このメソッドは、新しいデータが利用可能になるたびに起動され、ビューにアタッチするか反復するためonLoadFinished()の最新のデータが含まれます。Cursor

さらに、LoaderManagerクラスのドキュメンテーション ページには、これらすべてをうまく組み合わせたかなり良い例があります: http://developer.android.com/reference/android/app/LoaderManager.html

于 2011-08-24T22:48:55.387 に答える
10

誰かが同様の状況に陥った場合、私が行ったことは次のとおりです。

  • 必要なすべてのクエリを実装LoaderCallbacksして処理するクラスを作成しました。
  • これに aContextAdapter問題の を指定します。
  • 使用するクエリごとに一意の ID を作成します ( を使用する場合はUriMatcher、同じ ID を使用することもできます)。
  • に必要なバンドルにクエリを転送する便利なメソッドを作成します。LoaderCallbacks
  • それだけです:)私がしたことを正確に示すために、コードの一部を以下に示します

私のGlobalCallbacksクラスでは:

public static final String PROJECTION = "projection";
public static final String SELECTION = "select";
public static final String SELECTARGS = "sargs";
public static final String SORT = "sort";

Context mContext;
SimpleCursorAdapter mAdapter;

public GlobalCallbacks(Context context, SimpleCursorAdapter adapter) {
    mContext = context;
    mAdapter = adapter;
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {

    Uri contentUri = AbsProvider.customIntMatch(id);
    if (contentUri != null) {
        return new CursorLoader(mContext, contentUri, args.getStringArray(PROJECTION), args.getString(SELECTION), 
                args.getStringArray(SELECTARGS), args.getString(SORT));
    } else return null;

}

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
    mAdapter.swapCursor(arg1);      
}

@Override
public void onLoaderReset(Loader<Cursor> arg0) {
    mAdapter.swapCursor(null);
}

CursorLoaderそして、 (Helper.bundleArgs()は便利なバンドル方法です)を使用したい場合:

scAdapt = new Adapters.NewIndexedAdapter(mHost, getMenuType(), 
                null, new String[] { "name" }, new int[] { android.R.id.text1 });
        getLoaderManager().initLoader(
                GlobalCallbacks.GROUP,
                Helper.bundleArgs(new String[] { "_id", "name" }),
                new GlobalCallbacks(mHost, scAdapt));
        setListAdapter(scAdapt);

そしてヘルパーで:

public static Bundle bundleArgs(String[] projection, String selection, String[] selectionArgs) {
    Bundle b = new Bundle();
    b.putStringArray(GlobalCallbacks.PROJECTION, projection);
    b.putString(GlobalCallbacks.SELECTION, selection);
    b.putStringArray(GlobalCallbacks.SELECTARGS, selectionArgs);
    return b;
}

これが他の誰かに役立つことを願っています:)

編集

より徹底的に説明するには:

  • 最初に、null を持つアダプターCursorが初期化されます。アダプターに正しい入力を与えるCursorため、GlobalCallbacksCursoronLoadFinished(..)
  • 次に、LoaderManager新しい を初期化したいことを伝えますCursorLoader。カーソルの読み込みを監視する新しいGlobalCallbacksインスタンス ( を実装) を提供します。Loader.Callbacksアダプターも提供する必要があるため、Cursorロードが完了したら新しいものに交換できます。ある時点で、LoaderManager(OS に組み込まれている) が呼び出され、onCreateLoader(..)データのGlobalCallbacks非同期ロードが開始されます。
  • Helper.bundleArgs(..)Bundleクエリの引数を(列の射影、並べ替え順序、WHERE 句など)に入れるだけです。
  • 次に、 を設定しFragmentますListAdapter。この時点ではカーソルはまだ null のままであるため、onLoadFinished()が呼び出されるまで読み込み中のサインまたは空のメッセージが表示されます。
于 2011-09-20T16:27:51.240 に答える