この記事では、1つのアクティビティで異なるオブジェクトを読み込むためのローダー実装アプローチについて説明します。 Volleyは、ネットワークブートライブラリとして使用されます。 この方法は、1つのアクティビティで複数のフラグメントが同時に使用される場合に適しています
public class MainActivity extends ActionBarActivity implements LoaderManager.LoaderCallbacks<DataHolder>{ ... @Override public void onLoadFinished(Loader<DataHolder> loader, DataHolder data) { if ( loader.getId() == DataLoader.LOADER_ICONS_ID ){ doIcons( data.getIcons() ); } else if( loader.getId() == DataLoader.LOADER_STYLES_ID ){ doStyles( data.getStyles() ); } else if( loader.getId() == DataLoader.LOADER_ICONSETS_ID ){ doIconSets( data.getIconSets() ); }
フラグメントの使用に関する主な問題は、彼らが「自分の人生を生きている」ことです(そうでない場合は修正してください)。 特に画面を回すとき。 したがって、パラメーターと静的newInstanceのないコンストラクター(..)
newInstance public static IconsGridFragment newInstance(Icons icons) { IconsGridFragment fragment = new IconsGridFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_ICONS, icons); fragment.setArguments(args); return fragment; } public IconsGridFragment() { }
Fragmentのすべてのサブクラスには、引数なしのパブリックコンストラクターを含める必要があります。 フレームワークは、必要に応じて、特に状態の復元中に、フラグメントクラスを再インスタンス化することが多く、このコンストラクターを見つけてインスタンス化する必要があります。 引数なしのコンストラクターを使用できない場合、状態の復元中にランタイム例外が発生することがあります。
したがって、RetrofitまたはVolleyの助けを借りて非同期ロードを使用すると、状態ActivityとFragmentが存在するコールバックから戻るときに、100%確信することはできません。 FragmentManagerにはチェック可能な内部状態がありますが、これは悪いアプローチです。 例:
したがって、独自のローダーを作成することが決定されました。 テストのフィードは
Iconfinderによって選択され
ました 。 フィードは常にエラーなくリクエストに応じて提供されるとは限りません
E / Volley:[979] BasicNetwork.performRequest:httpsの予期しない応答コード429 ...たとえば、約100個のクエリを実行すると、エラーが返されます。 カスタマーサポートに書き込もうとしましたが、応答がありませんでした。 5秒後、エラーは消え、通常のリクエストが再開します。
Iconfinderからの回答:
429ステータスコードは、リクエストが多すぎることを意味します: developer.iconfinder.com/api/2.0/overview.html#rate-limited自分で推測できたかもしれません。 この機会に、アニメーションを含むポップアップウィンドウを作成しましたが、すべてフラグメントを使用して同じです。 5秒後にウィンドウを閉じてブートフラグをリセットします。 ft.commit()が実行された直後に、保留中のクローズメッセージが呼び出されます。 正しいものによると、フラグメントに参加するイベントを呼び出す必要があります。 たとえば、onAttachからのコールバック。
OverlayMessageFragmentを使用 private void closeOverlayDelay() { Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { closeOverlayFragment();
プロジェクト自体はgithub
Android Iconfinderデモで利用可能です

ローダーは次のとおりです。
public class DataLoader extends Loader<DataHolder> { public static final String ARGS_URL = "url"; private String urlFeed; private RequestQueue requestQueue; private DataHolder dataHolder = new DataHolder(); public static final int LOADER_ICONS_ID = 1; public static final int LOADER_STYLES_ID = 2; public static final int LOADER_ICONSETS_ID = 3; public DataLoader(Context context, Bundle bundle) { super(context); urlFeed = bundle.getString(ARGS_URL); requestQueue = Volley.newRequestQueue(context);
瞬間があります。 コールバックVolleyからすぐにデータを返すことはできません。または、すぐにdeliverResultのDataHolderを作成する方が正しいため、オブジェクトへの参照が格納されるDataHolderクラスのメンバーが必要です。
requestQueue.cancelAll(これ)を忘れないでください。 ローダーが中断したとき
また、小さなラッパーGsonRequestがVolley用に作成されました
しかし、それだけではありません。 onLoadFinishedを呼び出した後、フラグメントをすぐに起動することはできません。 ハンドラーによる追加の実装が必要になります。 stackoverflowで、彼らはバグについて書き、まさにそのような解決策を提供します:
ハンドラー final int ICONS_HANDLER = 1; final int STILES_HANDLER = 2; final int ICONSETS_HANDLER = 3; @Override public void onLoadFinished(Loader<DataHolder> loader, DataHolder data) { if(data == null ) {
フラグメント自体をBackStackに追加することは残っています。 さらに、すでに作成されているかどうかを確認し、作成されている場合は、単にアイコンをアダプタに追加します。 したがって、ページネーションの類似性が実装されます。または、LazyLoadMoreと呼ばれます。 バックグラウンドでアイコンとフィードをアップロードする
addToBackStack private void fillIcons(Icons icons) {
MainActivity.onStop()で、すべてのダウンロードを中断します。
private void destroyLoaders(){ mHandler.removeCallbacksAndMessages(null);
ロードの方法はすべて同じです。 次のステップは、次を使用して一般的な汎用クエリメソッドを実装することです。
Class<T> clazz;
次のようになります。
@Override public void onForceLoad() { super.onForceLoad(); doRequest(DataHolder.getClazz(getId())); }
DataHolderのクラスはDataHolderItemを実装する必要があります
public class Icons implements Parcelable, DataHolder.DataHolderItem{
データローダー public class DataLoader extends Loader<DataHolder> { private static final boolean DEBUG = true; private static final String TAG = "DataLoader>"; public static final String ARGS_URL = "url"; private String urlFeed; private RequestQueue requestQueue; private DataHolder dataHolder = new DataHolder(); public DataLoader(Context context, Bundle bundle) { super(context); urlFeed = bundle.getString(ARGS_URL); requestQueue = Volley.newRequestQueue(context);
データ所有者 public class DataHolder { public static final int LOADER_ICONS_ID = 1; public static final int LOADER_STYLES_ID = 2; public static final int LOADER_ICONSETS_ID = 3; private Styles styles; private Icons icons; private Iconsets iconsets; public Styles getStyles(){ return styles; } private void setStyles(Styles styles){ this.styles = styles; } public Iconsets getIconsets() { return iconsets; } private void setIconsets(Iconsets iconsets){ this.iconsets = iconsets; } public Icons getIcons(){ return icons; } private void setIcons(Icons icons){ this.icons = icons; } public void setData(int dataId, DataHolderItem item){ switch (dataId){ case LOADER_ICONS_ID: setIcons((Icons)item); break; case LOADER_STYLES_ID: setStyles((Styles)item); break; case LOADER_ICONSETS_ID: setIconsets((Iconsets)item); break; default: assert false : "Error LOADER ID"; } } public DataHolderItem getData(int dataId){ switch (dataId){ case LOADER_ICONS_ID: return getIcons(); case LOADER_STYLES_ID: return getStyles(); case LOADER_ICONSETS_ID: return getIconsets(); default: assert false : "Error LOADER ID"; } return null; } public static Class<?> getClazz(int dataId){ switch (dataId){ case LOADER_ICONS_ID: return Icons.class; case LOADER_STYLES_ID: return Styles.class; case LOADER_ICONSETS_ID: return Iconsets.class; default: assert false : "Error LOADER ID"; } return null; } public interface DataHolderItem{ } }
繰り返しますが、プロジェクトの完全な実装はgithub
Android Iconfinder demoで利用できます。 Apiアイコンファインダー
Api 2.0したがって、1つのActivityとFragmentsからの「サンドイッチ」が正しい画面回転を持つアプリケーションを取得しました
参照:
ローダーフラグメントローダーの実装