RxJava
组成
1. 上游 Observable
2. 下游 多种
无参的subscribe()表示下游不关心数据类型
带Cunsumer的表示下游只关心 onNext, 其他的装没看见
* public final Disposable subscribe() {}
* public final Disposable subscribe(Consumer<? super T> onNext) {}
* public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {}
* public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
* public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
* public final void subscribe(Observer<? super T> observer) {}
上有和下游之间可以添加各种参数
3. 水管 subscribe
4. 指定上游线程 subscribeOn()
多次指定上游线程, 只有第一次有效
5. 指定下游线程 observeOn()
下游线程可以多次指定
RxJava提供的线程
- Schedulers.io(), 代表io操作线程, 通常用于网络/读写等密集型操作
- Schedulers.computation, 代表CPu密集型计算
- Schedulers.newThread(), 代表一个常规的新线程
- AndroidSchedulers.mainThread(), 代表Android的主线程
RxJava内部使用线程池来维护, 所以效率也比较高
AndroidSchedulers.mainThread()是RxAndroid包里的
6.变换操作符
Map
截获事件水流
FlatMap
比Map更复杂, 将上游的Observable转化成多个Observable, 然后将他们发射的事件合并后放进一个单独的Observable里, 但是不保证事件顺序
concatMap
保证事件顺序的 FlatMap
实践
Retrofit连续请求
分为两个请求, 第一个请求, 根据经纬度向百度请求, 拿到转换出的城市名, 第二个请求, 请求和风天气, 将城市名转换成城市名对应的天气
- 准备好百度地图的城市json对应的bean
public class LocationEntity {
/**
* status : OK
* result : {"location":{"lng":121.490523,"lat":31.407452},"formatted_address":"上海市宝山区牡丹江路1599号","business":"友谊路,北翼商业街,吴淞","addressComponent":{"city":"上海市","direction":"near","distance":"0","district":"宝山区","province":"上海市","street":"牡丹江路","street_number":"1599号"},"cityCode":289}
*/
private String status;
private ResultBean result;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public ResultBean getResult() {
return result;
}
public void setResult(ResultBean result) {
this.result = result;
}
public static class ResultBean {
/**
* location : {"lng":121.490523,"lat":31.407452}
* formatted_address : 上海市宝山区牡丹江路1599号
* business : 友谊路,北翼商业街,吴淞
* addressComponent : {"city":"上海市","direction":"near","distance":"0","district":"宝山区","province":"上海市","street":"牡丹江路","street_number":"1599号"}
* cityCode : 289
*/
private LocationBean location;
private String formatted_address;
private String business;
private AddressComponentBean addressComponent;
private int cityCode;
public LocationBean getLocation() {
return location;
}
public void setLocation(LocationBean location) {
this.location = location;
}
public String getFormatted_address() {
return formatted_address;
}
public void setFormatted_address(String formatted_address) {
this.formatted_address = formatted_address;
}
public String getBusiness() {
return business;
}
public void setBusiness(String business) {
this.business = business;
}
public AddressComponentBean getAddressComponent() {
return addressComponent;
}
public void setAddressComponent(AddressComponentBean addressComponent) {
this.addressComponent = addressComponent;
}
public int getCityCode() {
return cityCode;
}
public void setCityCode(int cityCode) {
this.cityCode = cityCode;
}
public static class LocationBean {
/**
* lng : 121.490523
* lat : 31.407452
*/
private double lng;
private double lat;
public double getLng() {
return lng;
}
public void setLng(double lng) {
this.lng = lng;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
}
public static class AddressComponentBean {
/**
* city : 上海市
* direction : near
* distance : 0
* district : 宝山区
* province : 上海市
* street : 牡丹江路
* street_number : 1599号
*/
private String city;
private String direction;
private String distance;
private String district;
private String province;
private String street;
private String street_number;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getStreet_number() {
return street_number;
}
public void setStreet_number(String street_number) {
this.street_number = street_number;
}
}
}
}
- 准备 Rxjava 的 interface
public interface Api {
@GET("weather")
Observable<Weather2> getWeatherRx(
@Query("city")String city,
@Query("key")String key);
@GET("geocoder")
Observable<LocationEntity> getLoation(
@Query("location") String location,
@Query("output") String output,
@Query("key") String key
);
}
- 创建Retrofit
public class RetrofitCreater {
public static Retrofit createWeather() {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(9, TimeUnit.SECONDS);
builder.retryOnConnectionFailure(true);//错误时重复请求
builder.connectTimeout(15, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLogger());
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addNetworkInterceptor(interceptor);
}
return new Retrofit.Builder().baseUrl("https://free-api.heweather.com/v5/")
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
public static Retrofit createLoc() {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(9, TimeUnit.SECONDS);
builder.retryOnConnectionFailure(true);//错误时重复请求
builder.connectTimeout(15, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLogger());
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addNetworkInterceptor(interceptor);
}
return new Retrofit.Builder().baseUrl("http://api.map.baidu.com/")
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
}
- 调用Retrofit
private void requestRxLocation() {
Retrofit weatherRetrofit = RetrofitCreater.createWeather();
final Api weatherApi = weatherRetrofit.create(Api.class);
final Retrofit retrofitLoc = RetrofitCreater.createLoc();
Api locApi = retrofitLoc.create(Api.class);
locApi.getLoation("39.90400,116.39100", "json", "6eea93095ae93db2c77be9ac910ff311")
.flatMap(new Function<LocationEntity, ObservableSource<Weather2>>() {
@Override
public ObservableSource<Weather2> apply(LocationEntity locationEntity) throws Exception {
Log.i(tag, locationEntity.getResult().getAddressComponent().getCity()+"");
return weatherApi.getWeatherRx(locationEntity.getResult().getAddressComponent().getCity(), "你的和风天气key"); //拿到城市名, 开始请求天气接口
}
}).map(new Function<Weather2, String>() {
@Override
public String apply(Weather2 weather2) throws Exception {
String text = weather2.getHeWeather5().get(0).getBasic().getCity();
return text;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(tag,"accept"+s);
}
});
}
网友评论