1

Fragment の onCreate から initLoader は常に必要ですか? ローダーの重要な引数が別のローダーの結果に依存している場合はどうなりますか?

つまり、LoaderA と LoaderB の 2 つのローダーがあります。LoaderB を実行するには、LoaderA からの結果が必要です。LoaderA と LoaderB の両方がフラグメントの onCreate で初期化されますが、LoaderB には引数が与えられないため、意図的に失敗します。LoaderA が完了すると、LoaderB が新しい引数で再起動され、目的の要求を実行できるようになります。

フラグメントでのローダーの初期化:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    getLoaderManager().initLoader(LOADER_A, new Bundle(), this);
    getLoaderManager().initLoader(LOADER_B, null, mLoaderBCallback);
}

フラグメント内の LOADER_A のコールバック:

@Override
public Loader<MyResultObject> onCreateLoader(int id, Bundle args) { 
    return new LoaderA(getActivity(), args);
}

@Override
public void onLoadFinished(Loader<MyResultObject> loader, final MyResultObject result) {
    if (result != null) {
        Bundle args = new Bundle();
        args.putInt("id", result.getId());

        getLoaderManager().restartLoader(LOADER_B, args, mLoaderBCallback);
    }
}

フラグメントでの mLoaderBCallback の定義:

private LoaderBCallback mLoaderBCallback = new LoaderBCallback();

(LoaderBCallback の実装は重要ではありません。LoaderB のインスタンスを作成し、ローダーが終了したときに処理する標準の LoaderCallbacks インターフェイスです。)

LoaderB クラス (このクラス定義で潜在的なコンパイラ エラーが発生した場合はご容赦ください。これは単なる例です):

public class LoaderB<List<AnotherResultObject>> extends AsyncTaskLoader<List<AnotherResultObject>> { 
    private Bundle mArgs;

    public LoaderB(Context context, Bundle args) {
        super(context);
        mArgs = args;
    }

    @Override
    public List<AnotherResultObject> loadInBackground() {
        if (mArgs == null) {
            // bail out, no arguments.
            return null;
        }


        // do network request with mArgs here
        return MyStaticClass.performAwesomeNetworkRequest(mArgs);
    }

    // boiler plate AsyncTaskLoader stuff here
    ...... 

}

より良い方法はありますか?LoaderB の initLoader なしでできるでしょうか?

編集:ローダーは常にonCreateで初期化する必要があるという印象を受けています。これにより、構成の変更を処理できます。これは、アクティビティのローダーにのみ当てはまります。Fragments で作成されたローダーは、どこで初期化されても管理されますか?

4

1 に答える 1

1

コード内のどこからでもローダーを初期化できます。

あなたの場合、あなたはあなたrestartLoaderのinonLoadFinishedをに置き換える必要がありますinitLoader。onActivityCreatedforLOADER_BからinitLoaderを削除するだけです

また、onLoadFinishedでローダーのIDを確認して、どのローダーが終了したかを確認する必要があります。

編集:あなたはLOADER_Bコールバックに別のリスナーを使用しているので、私のIDチェックポイントはちょっとそこで敗北します..しかしとにかく..必要に応じてそれらを1つに組み合わせることができます

@Override
public void onLoadFinished(Loader<MyResultObject> loader, final MyResultObject result) {
    switch (loader.getId())
    {
      case LOADER_A:
         if (result != null) {
             Bundle args = new Bundle();
             args.putInt("id", result.getId());
             // i put "this" as the callback listener. you can use your custom one here if you want
             getLoaderManager().initLoader(LOADER_B, args, this);
         }
         break;
      case LOADER_B:
         //do whatever
         break;
}
于 2012-05-09T17:50:34.350 に答える