Rx-Java を使用して、Android での位置追跡用のクラスを作成しようとしています。私がまだ理解できないのは、Observable のライフサイクルを適切に処理する方法です。私が欲しいのは、最初のサブスクリプションが発生したときに位置の追跡を開始し、最後のサブスクリプションが破棄されたときに位置の追跡を停止する Observable です。これまでに達成したことは次のとおりです。
public class LocationObservable
implements GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener {
private LocationClient locationClient;
private final PublishSubject<Location> latestLocation =
PublishSubject.create();
public final Observable<Location> locationObservable =
Observable.defer(() -> {
if(!locationClient.isConnected() && !locationClient.isConnecting()) {
locationClient.connect();
}
return latestLocation.asObservable().scan((prev, curr) -> {
if (Math.abs(prev.getLatitude() - curr.getLatitude()) > 0.000001 ||
Math.abs(prev.getLongitude() - curr.getLongitude()) > 0.000001)
return curr;
else
return prev;
}).distinctUntilChanged();});
public LocationObservable(Context context) {
locationClient = new LocationClient(context, this, this);
}
@Override
public void onConnected(Bundle bundle) {
latestLocation.onNext(locationClient.getLastLocation());
}
@Override
public void onDisconnected() {
latestLocation.onCompleted();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
latestLocation.onError(new Exception(connectionResult.toString()));
}
@Override
public void onLocationChanged(Location location) {
latestLocation.onNext(location);
}
}
ご覧のとおりObservable#defer
、最初のクライアントがサブスクライブするときにロケーション コールバックを開始するために使用します。良いアプローチかどうかはわかりませんが、現時点で思いついたのはこれが最善です。私がまだ欠けているのは、クラスの最後のクライアントがオブザーバブルからサブスクライブを解除したときに位置情報の更新を停止する方法です。それとも、明らかではないため、Rxでは慣用的ではないものでしょうか?
私は、このユースケースはどちらかというと標準的なものであるべきだと考えています。したがって、標準的/慣用的なソリューションが必要です。知っていただければ幸いです。