16

私が達成したいこと:

2つの異なるフラグメントがあります。両方に同じデータを2つの形式(リストとマップ)で表示してほしい。AsyncTaskLoader(特に)1つのローダーを共有してほしい。すべて正常に動作しますが、ローダーは再利用されません。もう1つ作成され、データが2回ロードされます。

私がやること:

Fragment私が使用するのはLoaderManager lm = getActivity().getSupportLoaderManager(); 、両方で実装LoaderCallbacks<ArrayList<Item>>し、必要なメソッドです。両方で私は使用しますlm.initLoader(0, args, this);

しかし、出力するlm.toString()と、これらは2つの異なるローダーであるように見えます。そして、データは2回ダウンロードされます。

開始されたものとは異なるアクティビティ/フラグメントから同じローダーに再接続するにはどうすればよいですか?

onCreate()コンテキストは、構成の変更など、とにかくローダーにアタッチされるため、可能であるはずです。

4

4 に答える 4

5

開始されたものとは異なるアクティビティ/フラグメントから同じローダーに再接続するにはどうすればよいですか?

複数のsおよびsにまたがるインスタンスによって管理されているを再利用しないでください。LoaderLoaderManagerActivityFragment

は/ライフサイクルに関してLoaderManagerそれらを開始/停止するため、別のに入るとそれらが存在することを保証する方法はありません。LoaderActivityFragmentLoaderActivity

ドキュメントから:

LoaderManager.LoaderCallbacksは、クライアントがLoaderManagerと対話できるようにするコールバックインターフェイスです。

ローダー、特にCursorLoaderは、停止後もデータを保持することが期待されています。これにより、アプリケーションはアクティビティまたはフラグメントのonStop()メソッドとonStart()メソッド全体でデータを保持できるため、ユーザーがアプリケーションに戻ったときに、データがリロードされるのを待つ必要がありません。LoaderManager.LoaderCallbacksメソッドを使用して、新しいローダーを作成するタイミングを認識し、ローダーのデータの使用を停止するタイミングをアプリケーションに通知します。

つまり、Loaderアクティビティ(またはフラグメント)に固有のものになることがよくあります。インターフェイスをActivity実装するLoaderManager.LoaderCallbacksと、アクティビティにタイプが与えられますLoaderManager.LoaderCallbacks。を呼び出すたびに、LoaderManagerは、インターフェイスのインスタンス(この場合はアクティビティのインスタンス)に固有initLoader(int ID, Bundle args, LoaderCallbacks<D> callback)のを作成または再利用します。これは基本的にアクティビティをローダーにバインドし、ローダーの状態が変化するとそのコールバックメソッドが呼び出されます。LoaderLoaderManager.LoaderCallbacks

そうは言っても、2つの別々のアクティビティに同じコールバックメソッドを共有させる方法が見つからない限り、これを行うためのクリーンな方法があるとは思えません(つまり、アクティビティとフラグメントに同じコールバックを共有させるのは難しいように思えます、不可能ではないにしても)。でもあまり気にしない。これまでに見たすべてのサンプルコードで、2つのアクティビティやフラグメントが同じコールバックメソッドを共有しているのを見たことがありません。さらに、ActivitysとFragmentsの両方が再利用できるように設計されていることを考えるとLoader、この方法でsを共有することは、奨励されるようなものではないように思われます。

于 2012-04-07T18:24:09.843 に答える
1

はい。それは私のために働いた。ナビゲーションドロワーに3つの異なるフラグメントがあり、同じデータが異なるリストビューに入力されています。(すべてのフラグメントは同じアクティビティの一部です)。

私のAsyncTaskLoader:

public class MyTaskLoader extends AsyncTaskLoader<HashMap<String, Integer>> {

public MyTaskLoader(Context context) {
    super(context);
}

@Override
public HashMap<String, Integer> loadInBackground() {
...
return hashMap;
}

...
}

すべてのフラグメントで同じローダーIDを使用します。

フラグメント1:

public class Fragment1 extends BaseFragment implements LoaderManager.LoaderCallbacks<HashMap<String, Integer>> {
@Override
public void onCreate(Bundle savedInstanceState) {

//initialize adapter

getActivity().getSupportLoaderManager().initLoader(0, null, this);

}

@Override
public Loader<HashMap<String, Integer>> onCreateLoader(int arg0, Bundle arg1) {
    // TODO Auto-generated method stub

    return new MyTaskLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<HashMap<String, Integer>> arg0,
        HashMap<String, Integer> data) {
    // TODO Auto-generated method stub

    listAdapter.setData(data.keySet());

}

@Override
public void onLoaderReset(Loader<HashMap<String, Integer>> arg0) {
    // TODO Auto-generated method stub

    listAdapter.setData(null);
}
}

Fragment2に同じIDを使用します。

public class Fragment2 extends BaseFragment implements LoaderManager.LoaderCallbacks<HashMap<String, Integer>> {
@Override
public void onCreate(Bundle savedInstanceState) {

//initialize adapter

getActivity().getSupportLoaderManager().initLoader(0, null, this);

}

@Override
public Loader<HashMap<String, Integer>> onCreateLoader(int arg0, Bundle arg1) {
    // TODO Auto-generated method stub

    return new MyTaskLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<HashMap<String, Integer>> arg0,
        HashMap<String, Integer> data) {
    // TODO Auto-generated method stub

    listAdapter.setData(data.keySet());

}

@Override
public void onLoaderReset(Loader<HashMap<String, Integer>> arg0) {
    // TODO Auto-generated method stub

    listAdapter.setData(null);
}
}

ローダーを初期化する前に、アダプターを初期化する必要があります。これまでのところ動作します。しかし、これは正しい方法ですか?複数のフラグメントに共通のローダーを使用するためのより良い方法はありますか?

于 2015-01-06T05:42:41.190 に答える
0

話し合いを経て、あなたが何をアーカイブしようとしているのかよくわかりません。ただし、application.registerActivityLifecycleCallbacks()グローバルアクティビティライフサイクルリスナー(などonActivityCreated())を受け入れる方法があります。

于 2013-04-14T08:13:22.587 に答える
0

異なるフラグメントとアクティビティで同じローダーIDを使用すると、望ましい動作が得られると思います。ただし、ローダーIDがロードするデータに固有であることを確認してください。たとえば、PhotosLoaderとVideoLoaderは同じIDを持つべきではありません。

于 2016-08-31T19:56:18.167 に答える