ãã¡ãããä»ã¯2010幎ã§ã¯ãããŸãããéçºè ã¯æåãªA / B / Cãã¿ãŒã³ã䜿çšããããAsyncTask
以åã¯ãAndroidã§ãããã¯ãŒã¯ãªã¯ãšã¹ããå®è¡ããããã«äœ¿çšã§ããå¯äžã®ããŒã«ã¯Apacheã¯ã©ã€ã¢ã³ãã§ãããããã¯å®éã«ã¯çæ³ããã¯ã»ã©é ããã®ã§ãGoogleãæ°ããã¢ããªã±ãŒã·ã§ã³ã§ãããåãé€ãããã«äžçæžåœåªåããŠããããšã¯ç¡é§ã§ã¯ãããŸããã åŸã«ãHttpUrlConnectionã¯ã©ã¹ã¯ãGoogleéçºè ã®åªåã®çµæãšãªããŸããã 圌ã¯ç¶æ³ãããŸãä¿®æ£ããŸããã§ããã éåæãªã¯ãšã¹ããå®è¡ããããã®ååãªèœåã¯ãŸã ãããŸããã§ããããHttpUrlConnection + Loadersã¢ãã«ã¯ãã§ã«å€ããå°ãªããæ©èœããŠããŸãã
2013幎ã¯ãã®ç¹ã§éåžžã«å¹æçã«ãªããŸããã çŽ æŽããããã¬ãŒãšã¬ãããã£ããã®ã©ã€ãã©ãªãç»å ŽããŸããã Volleyã¯ãããã¯ãŒã¯ã§åäœããããã«èšèšãããããäžè¬çãªã©ã€ãã©ãªã§ãããRetrofitã¯REST Apiã§åäœããããã«ç¹ã«èšèšãããŠããŸãã ãããŠãã¯ã©ã€ã¢ã³ã/ãµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®éçºã§åºãèªããããæšæºãšãªã£ãæåŸã®ã©ã€ãã©ãªã§ããã
ã¬ãããã£ããã¯ãä»ã®æ段ãšæ¯èŒããŠãããã€ãã®äž»ãªå©ç¹ãåºå¥ã§ããŸãã
1ïŒããããèŠæ±ãæºããããã®å®å šãªæ©èœãæäŸããéåžžã«äŸ¿å©ã§ã·ã³ãã«ãªã€ã³ã¿ãŒãã§ã€ã¹ã
2ïŒæè»ãªæ§æ-ä»»æã®ã¯ã©ã€ã¢ã³ãã䜿çšããŠãªã¯ãšã¹ããå®è¡ããããjsonã解æããããã®ã©ã€ãã©ãªãªã©ã䜿çšãããã§ããŸãã
3ïŒjarãåå¥ã«è§£æããå¿ èŠã¯ãããŸãã-Gsonã©ã€ãã©ãªïŒããã³Gsonã®ã¿ ïŒ ããã®æ©èœãå®è¡ããŸãã
4ïŒçµæãšãšã©ãŒã®äŸ¿å©ãªåŠçã
5ïŒRxãµããŒãããããä»æ¥ã®éèŠãªèŠçŽ ã§ãã
Retrofitã©ã€ãã©ãªã«æ £ããŠããªãå Žåã¯ãä»ããåŠç¿ããŠãã ãã ã ãããããããã«ãããç§ã¯ç°¡åãªçŽ¹ä»ãè¡ããšåæã«ãããŒãžã§ã³2.0.0ã®æ°æ©èœãèŠãŠãããŸãïŒ Retrofit 2.0.0ã®ãã¬ãŒã³ããŒã·ã§ã³ãã芧ãã ããïŒã
äŸãšããŠãæ倧ã®ã·ã³ãã«ãã®ããã«ç©ºæž¯çšã®APIãéžæããŸããã ãããŠãæãäžè¬çãªåé¡ã解決ããŸã-æå¯ãã®ç©ºæž¯ã®ãªã¹ããååŸããŸãã
ãŸããéžæãããã¹ãŠã®ã©ã€ãã©ãªãšãRetrofitã«å¿ èŠãªäŸåé¢ä¿ãæ¥ç¶ããå¿ èŠããããŸãã
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1' compile 'com.squareup.okhttp:okhttp:2.0.0'
ç¹å®ã®ã¯ã©ã¹ã®ãªããžã§ã¯ãã®ãªã¹ãã®åœ¢åŒã§ç©ºæž¯ãåãåããŸãã
ãããã£ãŠããã®ã¯ã©ã¹ãäœæããå¿
èŠããããŸãã
public class Airport { @SerializedName("iata") private String mIata; @SerializedName("name") private String mName; @SerializedName("airport_name") private String mAirportName; public Airport() { } }
ãªã¯ãšã¹ãçšã®ãµãŒãã¹ãäœæããŸãã
public interface AirportsService { @GET("/places/coords_to_places_ru.json") Call<List<Airport>> airports(@Query("coords") String gps); }
Retrofit 2.0.0ã«é¢ãã泚æ
以åã¯ãåæèŠæ±ãšéåæèŠæ±ãå®è¡ããã«ã¯ãç°ãªãã¡ãœãããèšè¿°ããå¿ èŠããããŸããã ããã§ãvoidã¡ãœãããå«ããµãŒãã¹ãäœæããããšãããšããšã©ãŒãçºçããŸãã Retrofit 2.0.0ã§ã¯ãCallã€ã³ã¿ãŒãã§ãŒã¹ã¯ãªã¯ãšã¹ããã«ãã»ã«åãããªã¯ãšã¹ããåæçãŸãã¯éåæçã«å®è¡ã§ããããã«ããŸãã
以åã¯
public interface AirportsService { @GET("/places/coords_to_places_ru.json") List<Airport> airports(@Query("coords") String gps); @GET("/places/coords_to_places_ru.json") void airports(@Query("coords") String gps, Callback<List<Airport>> callback); }
ããŸ
AirportsService service = ApiFactory.getAirportsService(); Call<List<Airport>> call = service.airports("55.749792,37.6324949"); //sync request call.execute(); //async request Callback<List<Airport>> callback = new RetrofitCallback<List<Airport>>() { @Override public void onResponse(Response<List<Airport>> response) { super.onResponse(response); } }; call.enqueue(callback);
ãã«ããŒã¡ãœãããäœæããŸãã
public class ApiFactory { private static final int CONNECT_TIMEOUT = 15; private static final int WRITE_TIMEOUT = 60; private static final int TIMEOUT = 60; private static final OkHttpClient CLIENT = new OkHttpClient(); static { CLIENT.setConnectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS); CLIENT.setWriteTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); CLIENT.setReadTimeout(TIMEOUT, TimeUnit.SECONDS); } @NonNull public static AirportsService getAirportsService() { return getRetrofit().create(AirportsService.class); } @NonNull private static Retrofit getRetrofit() { return new Retrofit.Builder() .baseUrl(BuildConfig.API_ENDPOINT) .addConverterFactory(GsonConverterFactory.create()) .client(CLIENT) .build(); } }
ãããïŒ æºåãå®äºããèŠæ±ãæºãããããã«ãªããŸããã
public class MainActivity extends AppCompatActivity implements Callback<List<Airport>> { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AirportsService service = ApiFactory.getAirportsService(); Call<List<Airport>> call = service.airports("55.749792,37.6324949"); call.enqueue(this); } @Override public void onResponse(Response<List<Airport>> response) { if (response.isSuccess()) { List<Airport> airports = response.body(); //do something here } } @Override public void onFailure(Throwable t) { } }
ãã¹ãŠãéåžžã«ç°¡åã«æããŸãã å¿ èŠãªã¯ã©ã¹ãç°¡åã«äœæããŸãããã¯ãšãªãå®è¡ããçµæãååŸãããšã©ãŒãåŠçããããšã¯ããã¹ãŠæåéã10åã§è¡ããŸãã ä»ã«äœãå¿ èŠã§ããïŒ
ãã ãããã®ã¢ãããŒãã¯æ ¹æ¬çã«ééã£ãŠããŸãã ãªã¯ãšã¹ãã®å®è¡äžã«ããŠãŒã¶ãŒãããã€ã¹ãåããããã¢ããªã±ãŒã·ã§ã³ãéããããããšã©ããªããŸããïŒ èªä¿¡ãæã£ãŠèšãã°ãæã¿ã©ããã®çµæãä¿èšŒãããŠããããã§ã¯ãªããæåã®åé¡ããããã»ã©é ããªããšããããšã ãã§ãã ã¯ããã¢ã¯ãã£ããã£ãšãã©ã°ã¡ã³ãã®ãªã¯ãšã¹ãã¯ã³ãŒãã«çŸãããè¿œå ããŸããã ãããã£ãŠãæçµçã«èšäºã®ã¡ã€ã³ãããã¯ã§ããã¯ã©ã€ã¢ã³ããµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ã®æ§ç¯ã«æ»ããšããæ¥ãŸããã
ãã®ç¶æ³ã§ã¯ãããã€ãã®ãªãã·ã§ã³ããããŸãã ãã«ãã¹ã¬ããã§æèœãªäœæ¥ãæäŸããã©ã€ãã©ãªã䜿çšã§ããŸãã ç¹ã«RetrofitããµããŒãããŠãããããRxãã¬ãŒã ã¯ãŒã¯ã¯å®ç§ã§ãã ãã ããRxã䜿çšããŠã¢ãŒããã¯ãã£ãæ§ç¯ããããæ©èœçãªãªã¢ã¯ãã£ãããã°ã©ãã³ã°ã䜿çšãããããããšã¯ç°¡åãªäœæ¥ã§ã¯ãããŸããã ããç°¡åãªæ¹æ³ãåããŸãïŒAndroidãæäŸããããŒã«ããã®ãŸãŸäœ¿çšããŸãã ããªãã¡ãããŒããŒã
ããŒããŒã¯APIããŒãžã§ã³11ã§ç»å ŽããŸããããäŸç¶ãšããŠã¯ãšãªã®äžŠåå®è¡ã®ããã®éåžžã«åŒ·åãªããŒã«ã§ãã ãã¡ãããããŒããŒã§ã¯äœã§ãã§ããŸãããéåžžã¯ããŒã¿ããŒã¹ããããŒã¿ãèªã¿åããããããã¯ãŒã¯èŠæ±ãå®è¡ããããã«äœ¿çšãããŸãã ãããŠãããŒããŒã®æãéèŠãªå©ç¹ã¯ãLoaderManagerã¯ã©ã¹ãä»ããŠãã¢ã¯ãã£ããã£ãšãã©ã°ã¡ã³ãã®ã©ã€ããµã€ã¯ã«ã«é¢é£ä»ããããããšã§ãã ããã«ãããã¢ããªã±ãŒã·ã§ã³ãéãããšããŒã¿ã倱ãããããçµæãééã£ãã³ãŒã«ããã¯ã«æ»ã£ããããããšãæããã«ãããã䜿çšã§ããŸãã
éåžžãããŒããŒãæäœããã¢ãã«ã«ã¯æ¬¡ã®æé ãå«ãŸããŸãã
1ïŒèŠæ±ãæºãããçµæãååŸããŸãã
2ïŒäœããã®æ¹æ³ã§çµæããã£ãã·ã¥ããŸãïŒã»ãšãã©ã®å ŽåãããŒã¿ããŒã¹ã«ïŒã
3ïŒçµæãã¢ã¯ãã£ããã£ãŸãã¯ãã©ã°ã¡ã³ãã§è¿ããŸãã
ã泚æ
ActivityãFragmentã¯ããŒã¿ã®ååŸæ¹æ³ãèæ ®ããªãããããã®ãããªã¢ãã«ã¯åªããŠããŸãã ããšãã°ããµãŒããŒãããšã©ãŒãè¿ãããå ŽåããããŸãããåæã«ããŒããŒã¯ãã£ãã·ã¥ãããããŒã¿ãè¿ããŸãã
ãã®ãããªã¢ãã«ãå®è£ ããŸãããã ããŒã¿ããŒã¹ã®å®è£ æ¹æ³ã®è©³çŽ°ã¯çç¥ããŸãããå¿ èŠã«å¿ããŠãGithubã§äŸãèŠãããšãã§ããŸãïŒèšäºã®æåŸã®ãªã³ã¯ïŒã ããã§ãå€ãã®ããªãšãŒã·ã§ã³ãå¯èœã§ããããããã®å©ç¹ãšæ¬ ç¹ãé çªã«æ€èšããæçµçã«ã¯æé©ãšæãããã¢ãã«ã«å°éããŸãã
ã泚æ
ãã¹ãŠã®ããŒããŒã¯ãç°ãªãã¿ã€ãã®ããŒããããããŒã¿ã®1ã€ã®ã¢ã¯ãã£ããã£ãŸãã¯ãã©ã°ã¡ã³ãã§LoaderCallbacksã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšã§ããããã«ããŠãããŒãµã«ããŒã¿ã¿ã€ãã§åäœããå¿ èŠããããŸãã æåã«æãæµ®ãã¶ã®ã¯ãã«ãŒãœã«ã§ãã
ããäžã€ã®æ³šæ
ããŒããŒã«é¢é£ä»ããããŠãããã¹ãŠã®ã¢ãã«ã«ã¯å°ããªæ¬ ç¹ããããŸãããªã¯ãšã¹ãããšã«ãåå¥ã®ããŒããŒãå¿ èŠã§ãã ããã¯ãã¢ãŒããã¯ãã£ãå€æŽããããããšãã°å¥ã®ããŒã¿ããŒã¹ã«åãæ¿ããããããšãå€ãã®ãªãã¡ã¯ã¿ãªã³ã°ãçºçããããšãæå³ããŸãããããã¯ããŸãè¯ããããŸããã ãã®åé¡ãå¯èœãªéãåé¿ããããã«ããã¹ãŠã®ããŒããŒã«åºæ¬ã¯ã©ã¹ã䜿çšããå¯èœãªãã¹ãŠã®å ±éããžãã¯ãæ ŒçŽããŸãã
ããŒããŒ+ ContentProvider +éåæãªã¯ãšã¹ã
åææ¡ä»¶ïŒContentProviderãä»ããŠSQLiteããŒã¿ããŒã¹ãæäœããããã®ã¯ã©ã¹ãããããšã³ãã£ãã£ããã®ããŒã¿ããŒã¹ã«ä¿åããããšãã§ããŸãã
ãã®ã¢ãã«ã®ã³ã³ããã¹ãã§ã¯ãäžè¬çãªããžãã¯ãåºæ¬ã¯ã©ã¹ã«ããããšã¯éåžžã«å°é£ã§ããããããã®å ŽåãéåæèŠæ±ãå®è¡ããããã«ç¶æ¿ããã®ã«äŸ¿å©ãªããŒããŒã«ãããŸããã ãã®å 容ã¯åé¡ã®ã¢ãŒããã¯ãã£ã«çŽæ¥é©çšãããªãããããã¿ãã¬ã§ãã ãã ããã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšããããšãã§ããŸãã
ããŒã¹ããŒããŒ
public class BaseLoader extends Loader<Cursor> { private Cursor mCursor; public BaseLoader(Context context) { super(context); } @Override public void deliverResult(Cursor cursor) { if (isReset()) { if (cursor != null) { cursor.close(); } return; } Cursor oldCursor = mCursor; mCursor = cursor; if (isStarted()) { super.deliverResult(cursor); } if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { oldCursor.close(); } } @Override protected void onStartLoading() { if (mCursor != null) { deliverResult(mCursor); } else { forceLoad(); } } @Override protected void onReset() { if (mCursor != null && !mCursor.isClosed()) { mCursor.close(); } mCursor = null; } }
空枯ãããŒãããããã®ããŒããŒã¯æ¬¡ã®ããã«ãªããŸãã
public class AirportsLoader extends BaseLoader { private final String mGps; private final AirportsService mAirportsService; public AirportsLoader(Context context, String gps) { super(context); mGps = gps; mAirportsService = ApiFactory.getAirportsService(); } @Override protected void onForceLoad() { Call<List<Airport>> call = mAirportsService.airports(mGps); call.enqueue(new RetrofitCallback<List<Airport>>() { @Override public void onResponse(Response<List<Airport>> response) { if (response.isSuccess()) { AirportsTable.clear(getContext()); AirportsTable.save(getContext(), response.body()); Cursor cursor = getContext().getContentResolver().query(AirportsTable.URI, null, null, null, null); deliverResult(cursor); } else { deliverResult(null); } } }); } }
ãããŠãã€ãã«UIã¯ã©ã¹ã§äœ¿çšã§ããããã«ãªããŸããã
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getLoaderManager().initLoader(R.id.airports_loader, Bundle.EMPTY, this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { switch (id) { case R.id.airports_loader: return new AirportsLoader(this, "55.749792,37.6324949"); default: return null; } } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { int id = loader.getId(); if (id == R.id.airports_loader) { if (data != null && data.moveToFirst()) { List<Airport> airports = AirportsTable.listFromCursor(data); //do something here } } getLoaderManager().destroyLoader(id); } @Override public void onLoaderReset(Loader<Cursor> loader) { } }
ã©ããããè€éãªããšã¯äœããªãã ããã¯ãããŒããŒã®çµ¶å¯Ÿçãªæšæºäœæ¥ã§ãã ç§ã®æèŠã§ã¯ãããŒããŒã¯çæ³çãªã¬ãã«ã®æœè±¡åãæäŸããŸãã å¿ èŠãªããŒã¿ãããŒãããŸãããããŒãæ¹æ³ã«é¢ããäžå¿ èŠãªç¥èã¯ãããŸããã
ãã®ã¢ãã«ã¯å®å®ããŠããã䜿çšããã®ã«åå䟿å©ã§ããããŸã æ¬ ç¹ããããŸãïŒ
1ïŒæ°ããããŒããŒã«ã¯ãããããçµæãåŠçããããã®ç¬èªã®ããžãã¯ãå«ãŸããŠããŸãã ãã®æ¬ é¥ã¯ä¿®æ£ããããšãã§ããäžéšã¯æ¬¡ã®ã¢ãã«ã§ãå®å šã«åŸè ã§è¡ããŸãã
2ïŒ2çªç®ã®æ¬ ç¹ã¯ã¯ããã«æ·±å»ã§ãããã¹ãŠã®ããŒã¿ããŒã¹æäœã¯ã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ã¹ã¬ããã§å®è¡ãããããã倧éã®ããŒã¿ãä¿åãããŠã¢ããªã±ãŒã·ã§ã³ãåæ¢ããåã§ãã£ãŠããããŸããŸãªãã€ãã¹ã®çµæãæãå¯èœæ§ããããŸãã æåŸã«ãããŒããŒã䜿çšããŸãã éåæã§ãã¹ãŠããããŸãããïŒ
ããŒããŒ+ ContentProvider +åæãªã¯ãšã¹ã
åé¡ã¯ãããŒããŒãããã¯ã°ã©ãŠã³ãã§äœæ¥ãèš±å¯ããŠããã®ã«ããªãã¬ãããã£ããã䜿çšããŠãªã¯ãšã¹ããéåæã«å®è¡ããã®ã§ããïŒ ä¿®æ£ããŠãã ããã
ãã®ã¢ãã«ã¯åçŽåãããŠããŸãããäž»ãªéãã¯ãããŒããŒãä»ããŠèŠæ±ã®éåææ§ãéæãããããŒã¿ããŒã¹ã®æäœãã¡ã€ã³ã¹ã¬ããã§è¡ãããªãããšã§ãã åºæ¬ã¯ã©ã¹ã®çžç¶äººã¯ãCursoråã®ãªããžã§ã¯ãã®ã¿ãè¿ãå¿ èŠããããŸãã ããã§ãåºæ¬ã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
public abstract class BaseLoader extends AsyncTaskLoader<Cursor> { public BaseLoader(Context context) { super(context); } @Override protected void onStartLoading() { super.onStartLoading(); forceLoad(); } @Override public Cursor loadInBackground() { try { return apiCall(); } catch (IOException e) { return null; } } protected abstract Cursor apiCall() throws IOException; }
ãããŠãæœè±¡ã¡ãœããã®å®è£ ã¯æ¬¡ã®ããã«ãªããŸãã
@Override protected Cursor apiCall() throws IOException { AirportsService service = ApiFactory.getAirportsService(); Call<List<Airport>> call = service.airports(mGps); List<Airport> airports = call.execute().body(); AirportsTable.save(getContext(), airports); return getContext().getContentResolver().query(AirportsTable.URI, null, null, null, null); }
UIã§ã®ããŒããŒã®æäœã¯å€æŽãããŠããŸããã
å®éããã®ã¢ãã«ã¯ä»¥åã®ã¢ãã«ã®ä¿®æ£çã§ãããæ¬ ç¹ãéšåçã«æé€ããŠããŸãã ããããç§ã®æèŠã§ã¯ãããã¯ãŸã ååã§ã¯ãããŸããã ããã§ããæ¬ ç¹ã匷調ããããšãã§ããŸãã
1ïŒåããŒããŒã«ã¯ãããŒã¿ãä¿åããããã®åå¥ã®ããžãã¯ããããŸãã
2ïŒSQLiteããŒã¿ããŒã¹ã§ã®ã¿æ©èœããŸãã
ãããŠæåŸã«ããããã®æ¬ ç¹ãå®å šã«åãé€ããæ®éçã§ã»ãŒå®ç§ãªã¢ãã«ãæã«å ¥ããŸãããïŒ
ããŒããŒ+ä»»æã®ããŒã¿ã¹ãã¢+åæãªã¯ãšã¹ã
ç¹å®ã®ã¢ãã«ãæ€èšããåã«ãããŒããŒã§ã¯åäžã®ããŒã¿åã䜿çšããå¿ èŠããããšããäºå®ã«ã€ããŠèª¬æããŸããã ã«ãŒãœã«ä»¥å€ã«ã¯ãäœãæãæµ®ãã³ãŸããã ããã§ã¯ããã®ã¿ã€ããäœæããŸãããïŒ ãã®äžã«ã¯äœããããŸããïŒ åœç¶ããžã§ããªãã¯åã§ããã¹ãã§ã¯ãããŸããïŒããããªããšã1ã€ã®ã¢ã¯ãã£ããã£/ãã©ã°ã¡ã³ãã§ç°ãªãããŒã¿åã®ããŒããŒã³ãŒã«ããã¯ã䜿çšã§ããŸããïŒããåæã«ä»»æã®åã®ãªããžã§ã¯ãã®ã³ã³ãããŒã§ããå¿ èŠããããŸãã ãããŠãããã«ãã®ã¢ãã«ã®å¯äžã®åŒ±ç¹ããããŸã-ãªããžã§ã¯ãåã䜿çšããæªãã§ãã¯ã®å€æãå®è¡ããå¿ èŠããããŸãã ããã§ããããã¯å€§ããªãã€ãã¹ã§ã¯ãããŸããã ãã®ã¿ã€ãã®æçµããŒãžã§ã³ã¯æ¬¡ã®ãšããã§ãã
public class Response { @Nullable private Object mAnswer; private RequestResult mRequestResult; public Response() { mRequestResult = RequestResult.ERROR; } @NonNull public RequestResult getRequestResult() { return mRequestResult; } public Response setRequestResult(RequestResult requestResult) { mRequestResult = requestResult; return this; } @Nullable public <T> T getTypedAnswer() { if (mAnswer == null) { return null; } //noinspection unchecked return (T) mAnswer; } public Response setAnswer(@Nullable Object answer) { mAnswer = answer; return this; } public void save(Context context) { } }
ãã®ã¿ã€ãã¯ãã¯ãšãªã®çµæãä¿åã§ããŸãã ç¹å®ã®ãªã¯ãšã¹ãã«å¯ŸããŠäœãããããå Žåããã®ã¯ã©ã¹ããç¶æ¿ããå¿ èŠãªã¡ãœããããªãŒããŒã©ã€ã/è¿œå ããå¿ èŠããããŸãã ããšãã°ã次ã®ããã«ïŒ
public class AirportsResponse extends Response { @Override public void save(Context context) { List<Airport> airports = getTypedAnswer(); if (airports != null) { AirportsTable.save(context, airports); } } }
ãããïŒ ããŒããŒã®åºæ¬ã¯ã©ã¹ãäœæããŸãããã
public abstract class BaseLoader extends AsyncTaskLoader<Response> { public BaseLoader(Context context) { super(context); } @Override protected void onStartLoading() { super.onStartLoading(); forceLoad(); } @Override public Response loadInBackground() { try { Response response = apiCall(); if (response.getRequestResult() == RequestResult.SUCCESS) { response.save(getContext()); onSuccess(); } else { onError(); } return response; } catch (IOException e) { onError(); return new Response(); } } protected void onSuccess() { } protected void onError() { } protected abstract Response apiCall() throws IOException; }
ãã®ããŒããŒã¯ã©ã¹ã¯ããã®èšäºã®æçµçãªç®æšã§ãããç§ã®æèŠã§ã¯ãåªãããå®è¡å¯èœã§æ¡åŒµå¯èœãªã¢ãã«ã§ãã ããšãã°ãSQLiteããRealmã«ã¢ããã°ã¬ãŒããããã§ããïŒ åé¡ãããŸããã ããã次ã®äŸãšèããŠãã ããã ããŒããŒã®ã¯ã©ã¹ã¯å€æŽãããããããã®å Žåã§ãç·šéããã¢ãã«ã®ã¿ãå€æŽãããŸãã ãªã¯ãšã¹ããå®äºã§ããŸããã§ãããïŒ åé¡ã§ã¯ãããŸããããçžç¶äººã®apiCallã¡ãœãããå€æŽããŸãã ãšã©ãŒæã«ããŒã¿ããŒã¹ãã¯ãªã¢ãããã§ããïŒ onErrorãšworkããªãŒããŒã©ã€ãããŸã-ãã®ã¡ãœããã¯ããã¯ã°ã©ãŠã³ãã¹ã¬ããã§å®è¡ãããŸãã
ãŸããç¹å®ã®ããŒããŒã¯æ¬¡ã®ããã«è¡šãããšãã§ããŸãïŒããã§ããæœè±¡ã¡ãœããã®å®è£ ã®ã¿ã瀺ããŸãïŒã
@Override protected Response apiCall() throws IOException { AirportsService service = ApiFactory.getAirportsService(); Call<List<Airport>> call = service.airports(mGps); List<Airport> airports = call.execute().body(); return new AirportsResponse() .setRequestResult(RequestResult.SUCCESS) .setAnswer(airports); }
ã泚æ
ãªã¯ãšã¹ããæ£åžžã«å®è¡ãããªãã£ãå ŽåãäŸå€ãã¹ããŒãããããŒã¹ããŒããŒã®catchãã©ã³ãã«å°éããŸãã
ãã®çµæã次ã®çµæãåŸãããŸããã
1ïŒåããŒããŒã¯ããã®èŠæ±ïŒãã©ã¡ãŒã¿ãŒãšçµæïŒã®ã¿ã«äŸåããŸãããåæã«ãåä¿¡ããããŒã¿ãã©ãåŠçããããç¥ããŸããã ã€ãŸããç¹å®ã®ãªã¯ãšã¹ãã®ãã©ã¡ãŒã¿ãå€æŽããå Žåã«ã®ã¿å€æŽãããŸãã
2ïŒããŒã¹ããŒããŒã¯ãã¯ãšãªå®è¡ã®ããžãã¯å šäœãå¶åŸ¡ããçµæãåŠçããŸãã
3ïŒããã«ãã¢ãã«ã¯ã©ã¹èªäœã«ããããŒã¿ããŒã¹ãªã©ã®åŠçãã©ã®ããã«é 眮ãããŠãããã«ã€ããŠã®æãããããããŸããã ãããã¯ãã¹ãŠãåå¥ã®ã¯ã©ã¹/ã¡ãœããã§å®è¡ãããŸãã ããã¯ã©ãã«ãæ瀺çã«ç€ºããŠããŸããããGithubã®äŸïŒèšäºã®æåŸã«ãããªã³ã¯ïŒã§èŠãããšãã§ããŸãã
çµè«ã®ä»£ããã«
ããå°ãäžã«ãå¥ã®äŸã瀺ãããšãçŽæããŸãã-SQLiteããRealmãžã®ç§»è¡-ãããŠãããŒããŒã«å®éã«åœ±é¿ããªãããšã確èªããŸãã ãã£ãŠã¿ãŸãããã å®éãããã§ã®ã³ãŒãã¯ã»ãã®å°ãã§ããããŒã¿ããŒã¹ã®æäœã1ã€ã®æ¹æ³ã§ã®ã¿å®è¡ãããããã«ãªã£ãããã§ãïŒRealmã®è©³çŽ°ã«é¢é£ããå€æŽã¯èæ ®ããŠããŸããããç¹ã«ããã£ãŒã«ãã®åœåãšGsonã®æäœã«é¢ããã«ãŒã«ã§ãã Githubã«ãããŸãïŒã
ã¬ã«ã ã®æ¥ç¶ïŒ
compile 'io.realm:realm-android:0.82.1'
AirportsResponseã®ä¿åæ¹æ³ãå€æŽããŸãã
public class AirportsResponse extends Response { @Override public void save(Context context) { List<Airport> airports = getTypedAnswer(); if (airports != null) { AirportsHelper.save(Realm.getInstance(context), airports); } } }
空枯ãã«ããŒ
public class AirportsHelper { public static void save(@NonNull Realm realm, List<Airport> airports) { realm.beginTransaction(); realm.clear(Airport.class); realm.copyToRealm(airports); realm.commitTransaction(); } @NonNull public static List<Airport> getAirports(@NonNull Realm realm) { return realm.allObjects(Airport.class); } }
以äžã§ãïŒ åºæ¬çãªæ¹æ³ã§ãç°ãªãããžãã¯ãå«ãã¯ã©ã¹ã«åœ±é¿ãäžããããšãªããããŒã¿ã®ä¿åæ¹æ³ãå€æŽããŸããã
ãŸã çµè«
ããªãéèŠãªç¹ã匷調ããããšæããŸãããã£ãã·ã¥ãããããŒã¿ã®äœ¿çšã«é¢é£ããåé¡ãã€ãŸãã€ã³ã¿ãŒãããããªãå Žåã¯èæ ®ããŸããã§ããã ãã ããåã¢ããªã±ãŒã·ã§ã³ã§ãã£ãã·ã¥ãããããŒã¿ã䜿çšããæŠç¥ã¯åã ã®ãã®ã§ãããç¹å®ã®ã¢ãããŒãã課ãããšã¯é©åãšã¯èããŠããŸããã
ãã®çµæãã¯ã©ã€ã¢ã³ããµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ãæŽçããéã®äž»ãªåé¡ã調æ»ããŸããããã®èšäºãæ°ããããšãåŠã³ããããžã§ã¯ãã§äžèšã®ã¢ãã«ã®ããããã䜿çšããããšãé¡ã£ãŠããŸãã ããã«ããã®ãããªã¢ãŒããã¯ãã£ã®ç·šææ¹æ³ã«ã€ããŠç¬èªã®ã¢ã€ãã¢ãããã°ãæžããŠãã ããã
æåŸãŸã§èªãã§ãããŠããããšãã è¯ãéçºãïŒ
PS GitHubã®ã³ãŒããžã®çŽæããããªã³ã¯ã