2015年6月12日金曜日

SharedPrefenreces の値変更 + RxAndroid で状態の変更を
バックグラウンドのActivityに伝える

前回のエントリ「状態の変更をバックグラウンドのActivityに伝える方法はどれがいいんだろう?」の 3) を RxAndroid を使って実装してみました。

onStart() で値をチェックするのではなく、SharedPreferences の値が true になったイベントと起動時の処理を同じストリームになるようにしてみました。 public class MainActivity extends Activity { @InjectView(R.id.list) ListView listView; private Subscription subscription = Subscriptions.empty(); private static final String FAVORITE_PREF_KEY = "favorite_changed"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); final SharedPreferences pref = getSharedPreferences("reload_flag", MODE_PRIVATE); final Observable<List<String>> observable = ContentObservable.fromSharedPreferencesChanges(pref) .filter(new Func1<String, Boolean>() { @Override public Boolean call(String prefKey) { return FAVORITE_PREF_KEY.equals(prefKey) && pref.getBoolean(prefKey, false); } }) .startWith(FAVORITE_PREF_KEY) .flatMap(new Func1<String, Observable<List<String>>>() { @Override public Observable<List<String>> call(String s) { return Observable.create(new Observable.OnSubscribe<List<String>>() { @Override public void call(Subscriber<? super List<String>> subscriber) { try { subscriber.onNext(getDataFromServer()); } catch (Exception e) { subscriber.onError(e); } } }).subscribeOn(Schedulers.newThread()); } }); subscription = AppObservable.bindActivity(this, observable) .subscribe(new Subscriber<List<String>>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { e.printStackTrace(); pref.edit().putBoolean(FAVORITE_PREF_KEY, false).apply(); } @Override public void onNext(List<String> data) { listView.setAdapter(new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, data)); pref.edit().putBoolean(FAVORITE_PREF_KEY, false).apply(); } }); } private List<String> getDataFromServer() throws Exception { // mock Thread.sleep(1000); final Calendar c = Calendar.getInstance(); List<String> data = new ArrayList<>(); for (int i = 0; i < 20; i++) { data.add(i + " : " + DateFormat.format("hh時mm分ss秒", c)); } return data; } @Override protected void onDestroy() { subscription.unsubscribe(); super.onDestroy(); } @OnItemClick(R.id.list) void onItemClick(int position) { Intent intent = new Intent(this, SubActivity.class); startActivity(intent); } } public class SubActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sub); ButterKnife.inject(this); } @OnClick(R.id.favorite_button) void onFavoriteButtonClicked() { // サーバー通信とかして、状態を変更できたとする final SharedPreferences pref = getSharedPreferences("reload_flag", MODE_PRIVATE); pref.edit().putBoolean("favorite_changed", true).apply(); } }

SubActivity でボタンをクリックすると、MainActivity でリロードが走ります。



0 件のコメント:

コメントを投稿