LoaderManagerの範囲は何ですか?
質問
LoaderManagerでローダーを識別する場合、一意のIDを使用します。私はそれらのIDがどれほどユニークであるかについて尋ねています。
すべてのアクティビティとフラグメントには独自のロードマネージャーがありますか?フラグメントは、付着しているアクティビティのロードマナージャーを使用していますか?アプリケーションが所有するLoaderManagerは1つだけですか?
ボーナスポイントあなたが使用しているロードマナージャーをどのように変更するかを教えてください。アクティビティ内のすべてのフラグメントに同じロードマネージャーを使用したい場合(それらの一部は同じデータを引いてローダーを共有するのがいいでしょう)、それは可能ですか?
解決
現在、アプリケーションをAndroid互換性パッケージに移植しています(主にCursorloaderとFragments用)。現在、2つのフラグメント間でカーソルローダーを共有して、ContentSproviderへのクエリをspareしようとしています。私の世界へようこそ! ;)
単純なユースケース:
- dummyActivityはfragmentactivity / log.d(constants.logtag、 "dummyact.oncreate" + getSupportloadermanager()。toString());
- dataFragment拡張フラグメントexplention loadermanager.loadercallbacks / log.d(constants.logtag、 "dataFragment.oncreate" + getLoaderManager()。toString());
- ReportFragmentはフラグメントを拡張しますRoaderManager.LoaderCallbacks / log.d(constants.logtag、 "reportfragment.oncreate" + getLoaderManager()。toString());
DummyActivityはデータフラージュをインスタンス化し、その後のレポートフラグメントをインスタンス化します。 LogCat出力は、各LoaderManagerの異なるアドレスを示しています。最初の結論として、各フラグメントには適切なロードマネージャーがいるようです…
あなたの(私たちの)質問に答えることができれば、私は続けて更新します。進歩を遂げた場合は、貴重な知識を共有してください。
アップデート:
私の仮定は、ローダーIDは、いくつかのローカルローダーをフラグメントに関連付けることができるように、特定のフラグメントのローダーマネージャーのローカルスコープにのみ関連付けられているということです(したがって、ID int argとThe the the the oncreateloaderの別のローダーを返すことができます。 Initolader呼び出し)。
これまでのところ、私はなんとかローダーを「再利用」することができました(…かどうか):
- 最初に、LoaderManagerのデバッグを有効にしました getSupportLoaderManager().enableDebugLogging(true);
ダミーアクティブで onCreate
方法。
- それから私は電話しました getActivity().getSupportLoaderManager().initLoader(78, null, this);
から onCreate
データフラージュとレポートフラグメントの両方の方法。
-dataFragmentは、によって作成されたCursorLoaderを公開します onCreateLoader
McUrsorloaderプライベートメンバーのセッターを介した方法。
- レポートフラグメント onCreateLoader
DataFragment CursorLoaderを返します(でフラグメントを取得した後 findFragmentByTag
).
フィルタリングされた(およびわずかに難読化された)ログキャット出力:
DummyApp D DummyActivity.onCreate
DummyApp D DataFragment.newInstance
DummyApp D ReportFragment.newInstance
DummyApp D DataFragment.onCreate
LoaderManager V initLoader in LoaderManager{405a19d0 in SpecificAction{4059ee98}}: args=null
DummyApp D DataFragment.onCreateLoader
LoaderManager V Created new loader LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
DummyApp D DataFragment.onCreate
DummyApp D DataFragment.onActivityCreated
DummyApp D ReportFragment.onCreate
LoaderManager V initLoader in LoaderManager{405a19d0 in DummyActivity{4059ee98}}: args=null
LoaderManager V Re-using existing loader LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
DummyApp D SpecificActionReportFragment.onCreate
DummyApp D SpecificActionReportFragment.onActivityCreated
LoaderManager V Starting in LoaderManager{405a19d0 in DummyActivity{4059ee98}}
LoaderManager V Starting: LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
DummyProvider D query called
DummyProvider D […]
DummyProvider D [end of query]
LoaderManager V onLoadComplete: LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
LoaderManager V onLoadFinished in CursorLoader{405a22e0 id=78}: CursorWrapperInner{405afb20}
DummyApp D ReportFragment.onLoadFinished
DummyApp D ReportFragment.displayActionReport
DummyApp D DummyActivity.setReportViewsVisibility
DummyApp D ReportFragment.setSaveReportImageViewVisibility
2つのフラグメントは、ダミー活動から追加されます onCreate
方法(説明されているユースケースとは異なりますが、それは私たちが取り組んでいる問題に何も変わりません)。残念ながら、ローダーはそうです 再割り当て それを呼ぶ最新のフラグメントに(ここで報告されたもの)…そしてdataFragment.onloadFinishedは決して呼ばれません。結果として、レポートフラグメントは良さそうに見えますが、更新がから呼び出されているため、データフラージュは最新ではありません。 onLoadFinished
このクラスの。
基礎となるUnregisterコールがあり、CursorLoaderのレジスタコールがあると思います。
つづく…
他のヒント
はい。それは私のために働いた。同じデータが異なるListViewに入力されているナビゲーション引き出しには、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を使用します。
fragment1:
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);
}
}
ローダーを初期化する前に、アダプターを初期化する必要があります。これまでのところうまくいきます。しかし、これは正しい方法ですか?複数のフラグメントに一般的なローダーを使用するためのより良い方法はありますか?