RxAndroid v1.0.0からのライフサイクルへのバインド方法

RxAndroidをv1.0.0に更新していたところ、`AppObservable`の部分がすべてエラーになっており、それを解消するまでに案外手間取ってしまったのでそのメモ

# AppObservableとは

`Activity`や`Fragment`内部で`Observable#subscribe()`を呼んだ際、その`Activity`や`Fragment`が終了された以降にも`onNext`や`onCompleted`が呼ばれてしまうことがあります。
その結果、画面が破棄された状態で画面更新を行おうとしてしまうことでのエラーや、`Observable`が`Activity`や`Fragment`への強参照を持ったままになってしまうことによるメモリリークが発生してしまいます。
それを防ぐために`onPause`などで明示的に`Subscription#unsubscribe()`を呼んであげる必要がありました。

その`unsubscribe`の処理を勝手にやってくれる仕組みが`AppObservable`でした。
以下の様な感じに`Observable`をラップすることで使用できました。


```HogeActivity.java
public class HogeActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hoge);

        // hogeTask()の返り値がObservable
        AppObservable.bindActivity(this, hogeTask()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread()))
            .subscribe(data -> {
               // 処理
            });
    }
}
```

# RxAndroid v1.0.0での変更

今までRxAndroidのライブラリの中に同梱されていた`AppObservable`の代わりに、別のライブラリを使用する方法へ置き換えられました。

https://github.com/trello/RxLifecycle

使う際は`build.gradle`に以下を加えてください。
（バージョンは15/10/04時点での最新バージョンです）

```groovy
compile 'com.trello:rxlifecycle:0.3.0'
compile 'com.trello:rxlifecycle-components:0.3.0'
```


クラス名の変更だけでなく、使い方も大幅に変わりました。
先ほどの`AppObservable`を使用していた例を`RxLifecycle`の仕様に書き換えてみます。

```HogeActivity.java
public class HogeActivity extends RxActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hoge);

        // hogeTask()の返り値がObservable
        hogeTask()
            .compose(bindToLifecycle())
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(data -> {
                // 処理
            });
    }
}
```

1. Activityの継承元を`RxActivity`に変更
2. `AppObservable`で囲う方式から、`compose()`で処理をつなげる方式に変更

継承元の`RxActivity`は、もともとのActivityが何のActivityを継承していたかで変わります
>例：
 ・ `AppCompatActivity` -> `RxAppCompatActivity`
 ・ `AppFragmentActivity` -> `RxFragmentActivity`

Fragementの場合も同様に継承元を変更（`RxFragment`など）することで`bindToLifecycle()`を使用することができます。

`bindToLifecycle`メソッドは、対象の`Observable`の`subscribe`メソッドが呼ばれた時のライフサイクルの状態に応じて、自動的に終わりのライフサイクルを決定してくれます。

>例：
 ・ `onCreate`の中で`subscribe`が呼ばれた時は`onDestory`で`unsubscribe`される
 ・ `onResume`の中で`subscribe`が呼ばれた時は`onPause`で`unsubscribe`される

unsubscribeされる状態を自分で決定したい場合は、`bindToLifecycle()`を`bindUntilEvent(ActivityEvent.STOP)`のように書き換えてください（`onStop`で`unsubscribe`）

また、注意点として、自動的に`unsubscribe`が行われる際には、自動的に`onCompleted`が呼ばれます。
もし、onCompletedでActivityなどへアクセスするコードを書いている場合は、`RxLifecycle`を使用するのではなく通常通り`Subscription`を各自で`unsubscribe`したほうがいいようです。

>In most cases this works out fine (since onCompleted() is not often used). In cases where you do not want onCompleted() called during early termination, then it is suggested that you manually handle the Subscription yourself and call unsubscribe() when appropriate.
https://github.com/trello/RxLifecycle/blob/master/README.md

# RxActivityを継承したくない

`RxActivity`内部で行われている動作は、

1. on***から得られたライフサイクルのイベントを
2. `Observable`に流す

という単純な動作しかしていません。
継承を多段にしたくない・すでに`BaseActivity`/`BaseFragment`を用意しているから、そこにマージさせたい といった場合は、この処理を自前で書くと良いでしょう

```BaseActivity.java
// Fragmentであれば、AcitivtyEventではなくFragmentEvent
// メソッド名に含まれるActivityという単語もFragmentに置き換える
private final BehaviorSubject<ActivityEvent> lifecycle = BehaviorSubject.create();

@Override
public final <T> Observable.Transformer<? super T, ? extends T> bindUntilEvent(ActivityEvent event) {
    return RxLifecycle.bindUntilActivityEvent(lifecycle, event);
}

public final <T> Observable.Transformer<? super T, ? extends T> bindToLifecycle() {
    return RxLifecycle.bindActivity(lifecycle);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    lifecycle.onNext(FragmentEvent.CREATE);
}

// Activityであれば、onCreate, onStart, onResume, onPause, onStop, onDestoryで lifecycle.onNext(ActivityEvent.***);を呼ぶ
// Fragmentであれば、onAttach, onCreate, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestory, onDetachでlifecycle.onNext(FragmentEvent.***);を呼ぶ
```

自前で用意したことにより、`RxActivity`や`RxFragment`を使用しない場合は

```groovy
compile 'com.trello:rxlifecycle-components:0.3.0'
```
こちらの依存関係は削除してしまって問題ありません。

# おわりに

`AppObservable`の時より、`compose`でつなげていくほうがRxらしくてより理想的になっている気がしました。