Day23-RxJava&Retrofit

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连续请求

分为两个请求, 第一个请求, 根据经纬度向百度请求, 拿到转换出的城市名, 第二个请求, 请求和风天气, 将城市名转换成城市名对应的天气

  1. 准备好百度地图的城市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;
            }
        }
    }
}
  1. 准备 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
    );
}
  1. 创建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();
    }
}
  1. 调用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);
                }
            });


}

database

推荐阅读更多精彩内容