既存の自作アプリに、RxJavaを一部導入した話です。
メモとして。
今回の範囲
- AndroidのプロジェクトにRxJavaを導入する
- ラムダ式を使えるようにする
- とりあえずなんかやってみる(リスト操作)
RxJavaを導入する
RxJavaを導入すること自体は、そんなに大変ではありませんでした。
とりあえず、build.gradleに、RxJavaの依存を追加するだけです。
dependencies {
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.1
}
これで、RxJavaの機能が使えるようになります。
ラムダ式を使えるようにする
ラムダ式を使えるようにするには、Java 8でコーディングする旨の記述が必要です。
こちらもbuild.gradleに追加します。
android {
...
defaultConfig {
...
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
こちらが参考になります。
Java 8 の言語機能を使う | Android Developers
一方で、これを有効にするデメリットもありまして。。
Instant Run 機能は、現段階では Jack と併用できません
とのこと。
Instant Run自体かなり便利な機能なので、レイアウトを実装中にはちょっと不便かも。
試してないけど、RetroLambdaを使うようにしたら、Jack使わなくてもいいのかな?
とりあえずなんかやってみる(リスト操作)
もとの実装
とりあえず、リスト操作をRxっぽく書いてみることにしました。
通信などを使用しないアプリなので、あんまりRxJavaの恩恵は受けられないのですが……。
もともとは、ざっくり以下のようなコードでした。
class MyAdapter extends ArrayAdapter<Item> {
public MyAdapter(Context context, List<Item> objects) {
super(context, 0, objects);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
ViewItemListBinding binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.view_item_list, parent, false);
convertView = binding.getRoot();
}
ViewItemListBinding binding = DataBindingUtil.getBinding(convertView);
binding.setItem(getItem(position));
return convertView;
}
}
DataBindingを使用しているので、データをViewに当てる処理はここには書いていません。
しかしながら、getItem(position)
のところで、
ItemデータをViewに当てようとしている意図は理解していただけるかと思います。
Itemクラスは、データそのもの、モデルクラスです。
導入後
以下のようになりました。
class MyAdapter extends ArrayAdapter<Item> {
// Item(リスト)のObservableを追加
Observable<Item> itemObservable;
public MyAdapter(Context context, List<Item> objects) {
super(context, 0, objects);
// ItemのリストでObservableを生成
itemObservable = Observable.fromIterable(objects);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
ViewItemListBinding binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.view_item_list, parent, false);
convertView = binding.getRoot();
}
ViewItemListBinding binding = DataBindingUtil.getBinding(convertView);
// Itemのシーケンスから、ポジション(int)でfilterしてItemを抽出する
binding.setItem(itemObservable.filter(item -> item.isEqualToPosition(position)).blockingFirst());
return convertView;
}
}
item.isEqualToPosition()
は、boolを返すItemクラスのメソッドです(今回のために無理やり追加した)。
見ての通り、スーパークラスに渡したitemsを使用しない実装になるので、itemsの中身が変わるなどすると、不具合を起こすかもしれません。
しかしながら、練習にはちょうどよかったです。
今回の実装では、RxJavaの恩恵を受けにくい実装になりましたが、雰囲気はつかめたと思います。