如何使用 RxAndroid 将流正确拆分为 4 个操作?
How to split a stream correctly into 4 Actions using RxAndroid?
我第一次尝试响应式编程。我正在为 Android 使用 ReactiveLocation 库,并且我有 4 个文本视图需要在收到新位置时填充位置数据。
这是让我在每次位置更新时获得位置的代码:
locationProvider = new ReactiveLocationProvider(getApplicationContext());
lastKnownLocationObservable = locationProvider.getLastKnownLocation();
final LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setNumUpdates(150)
.setInterval(100);
locationUpdatesObservable = locationProvider
.checkLocationSettings(
new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
.setAlwaysShow(true) //Refrence:
.build()
)
.doOnNext(new Action1<LocationSettingsResult>() {
@Override
public void call(LocationSettingsResult locationSettingsResult) {
Status status = locationSettingsResult.getStatus();
if (status.getStatusCode() == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
try {
status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException th) {
Log.e("MainActivity", "Error opening settings activity.", th);
}
}
}
})
.flatMap(new Func1<LocationSettingsResult, Observable<Location>>() {
@Override
public Observable<Location> call(LocationSettingsResult locationSettingsResult) {
return locationProvider.getUpdatedLocation(locationRequest);
}
});
我还有这个 Func,它将位置拆分为 4 个字符串的数组:
public class LocationToStringsArrayListFunc implements Func1<Location, ArrayList<String>> {
@Override
public ArrayList<String> call(Location location) {
ArrayList<String> locationDetails = null;
if (location != null) {
locationDetails = new ArrayList<>();
locationDetails.add(String.valueOf(location.getLatitude()));
locationDetails.add(String.valueOf(location.getLongitude()));
locationDetails.add(String.valueOf(location.getTime()));
locationDetails.add(String.valueOf(location.getSpeed()));
}
return locationDetails;
}
}
最后我有了这个操作来用文本填充 TextView:
public class DisplayTextOnViewAction implements Action1<String> {
private final TextView target;
public DisplayTextOnViewAction(TextView target) {
this.target = target;
}
@Override
public void call(String s) {
target.setText(s);
}
}
我现在想要的是每次将此流拆分为 4 个视图,我知道我将执行以下操作:
mUpdatableLocationSubscription = locationUpdatesObservable
.map(new LocationToStringsArrayListFunc())
.map(new Func1<ArrayList<String>, String>() {
@Override
public String call(ArrayList<String> stringArrayList) {
return stringArrayList.get(0);
}
})
.subscribe(new DisplayTextOnViewAction(tvLatitudeValue), new ErrorHandler());
如何使用相同的流填充其他 3 个 TextView:LongitudeValue、tvLastUpdateValue、tvSpeedValue?
.share()
运算符是您应该查看的内容。
有了这个 "helper" class :
public class ListItemFunc extends Func1<ArrayList<String>, String>{
private final int index;
public ListItemFunc(int index) {
this.index = index;
}
@Override
public String call(ArrayList<String> strings) {
return strings.get(index);
}
}
您的代码可以如下所示:
Observable<ArrayList<String>> sharedObservable =
locationUpdatesObservable.map(new LocationToStringsArrayListFunc()).share();
latitudeSubscription = sharedObservable
.map(new ListItemFunc(0))
.subscribe(new DisplayTextOnViewAction(tvLatitudeValue), new ErrorHandler());
longitudeSubscription = sharedObservable
.map(new ListItemFunc(1))
.subscribe(new DisplayTextOnViewAction(tvLongitudeValue), new ErrorHandler());
lastUpdateSubscription = sharedObservable
.map(new ListItemFunc(2))
.subscribe(new DisplayTextOnViewAction(tvLastUpdateValue), new ErrorHandler());
speedSubscription = sharedObservable
.map(new ListItemFunc(3))
.subscribe(new DisplayTextOnViewAction(tvSpeedValue), new ErrorHandler());
我第一次尝试响应式编程。我正在为 Android 使用 ReactiveLocation 库,并且我有 4 个文本视图需要在收到新位置时填充位置数据。
这是让我在每次位置更新时获得位置的代码:
locationProvider = new ReactiveLocationProvider(getApplicationContext());
lastKnownLocationObservable = locationProvider.getLastKnownLocation();
final LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setNumUpdates(150)
.setInterval(100);
locationUpdatesObservable = locationProvider
.checkLocationSettings(
new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
.setAlwaysShow(true) //Refrence:
.build()
)
.doOnNext(new Action1<LocationSettingsResult>() {
@Override
public void call(LocationSettingsResult locationSettingsResult) {
Status status = locationSettingsResult.getStatus();
if (status.getStatusCode() == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
try {
status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException th) {
Log.e("MainActivity", "Error opening settings activity.", th);
}
}
}
})
.flatMap(new Func1<LocationSettingsResult, Observable<Location>>() {
@Override
public Observable<Location> call(LocationSettingsResult locationSettingsResult) {
return locationProvider.getUpdatedLocation(locationRequest);
}
});
我还有这个 Func,它将位置拆分为 4 个字符串的数组:
public class LocationToStringsArrayListFunc implements Func1<Location, ArrayList<String>> {
@Override
public ArrayList<String> call(Location location) {
ArrayList<String> locationDetails = null;
if (location != null) {
locationDetails = new ArrayList<>();
locationDetails.add(String.valueOf(location.getLatitude()));
locationDetails.add(String.valueOf(location.getLongitude()));
locationDetails.add(String.valueOf(location.getTime()));
locationDetails.add(String.valueOf(location.getSpeed()));
}
return locationDetails;
}
}
最后我有了这个操作来用文本填充 TextView:
public class DisplayTextOnViewAction implements Action1<String> {
private final TextView target;
public DisplayTextOnViewAction(TextView target) {
this.target = target;
}
@Override
public void call(String s) {
target.setText(s);
}
}
我现在想要的是每次将此流拆分为 4 个视图,我知道我将执行以下操作:
mUpdatableLocationSubscription = locationUpdatesObservable
.map(new LocationToStringsArrayListFunc())
.map(new Func1<ArrayList<String>, String>() {
@Override
public String call(ArrayList<String> stringArrayList) {
return stringArrayList.get(0);
}
})
.subscribe(new DisplayTextOnViewAction(tvLatitudeValue), new ErrorHandler());
如何使用相同的流填充其他 3 个 TextView:LongitudeValue、tvLastUpdateValue、tvSpeedValue?
.share()
运算符是您应该查看的内容。
有了这个 "helper" class :
public class ListItemFunc extends Func1<ArrayList<String>, String>{
private final int index;
public ListItemFunc(int index) {
this.index = index;
}
@Override
public String call(ArrayList<String> strings) {
return strings.get(index);
}
}
您的代码可以如下所示:
Observable<ArrayList<String>> sharedObservable =
locationUpdatesObservable.map(new LocationToStringsArrayListFunc()).share();
latitudeSubscription = sharedObservable
.map(new ListItemFunc(0))
.subscribe(new DisplayTextOnViewAction(tvLatitudeValue), new ErrorHandler());
longitudeSubscription = sharedObservable
.map(new ListItemFunc(1))
.subscribe(new DisplayTextOnViewAction(tvLongitudeValue), new ErrorHandler());
lastUpdateSubscription = sharedObservable
.map(new ListItemFunc(2))
.subscribe(new DisplayTextOnViewAction(tvLastUpdateValue), new ErrorHandler());
speedSubscription = sharedObservable
.map(new ListItemFunc(3))
.subscribe(new DisplayTextOnViewAction(tvSpeedValue), new ErrorHandler());