OKHttp & Retrofit & RxJava

130 阅读4分钟

1、OKHttp基本使用 - get请求

        /*1.创建OkHttpClient对象*/
        OkHttpClient httpClient = new OkHttpClient();
        /*2.创建请求Request内容*/
        Request request = new Request.Builder()
                .method("GET", null)
                .url("https://www.baidu.com/")
                .build();
        /*3.发送请求*/
        Call call = httpClient.newCall(request);
        /*4.创建请求的回调*/
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "请求失败的原因:" + e);
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                Headers headers = response.headers();
                Set<String> names = headers.names();
                for (String name : names) {
                    Log.e(TAG, "请求的header" + name);
                    String value = headers.get(name);
                    Log.e(TAG, "值为: " + value + "\n----------------------------------");
                }


                final String date = response.body().string();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mTvShow.setText(date);
                    }
                });
            }
        });

2、OKHttp简单使用-post请求

        /*1.创建OkHttpClient对象*/
        OkHttpClient httpClient = new OkHttpClient();
        /*2.创建相应的表单内容*/
        FormBody formBody = new FormBody.Builder()
                .add("key", "value")
                .build();
        /*3.创建请求Request内容*/
        Request request = new Request.Builder()
                .url("https://www.baidu.com/")
                .post(formBody)
                .build();
        /*4.发送请求*/
        Call call = httpClient.newCall(request);
        /*5.创建请求的回调*/
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "请求失败的原因:" + e);
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                Headers headers = response.headers();
                Set<String> names = headers.names();
                for (String name : names) {
                    Log.e(TAG, "请求的header" + name);
                    String value = headers.get(name);
                    Log.e(TAG, "值为: " + value + "\n----------------------------------");
                }


                final String date = response.body().string();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mTvShow.setText(date);
                    }
                });
            }
        });
    }

3、OKHttp基本使用 - 文件上传

        /*1.创建OkHttpClient对象*/
        OkHttpClient httpClient = new OkHttpClient();
        /*2.创建相应的表单内容*/
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("title", "张三")
                .addFormDataPart("image", "zhangsan.jpg", RequestBody.create(MediaType.parse("application/octet-stream"), new File(Environment.getExternalStorageDirectory().getParent() + "/0/123.png")))
                .build();

        /*3.创建请求Request内容*/
        Request request = new Request.Builder()
                .header("key", "value")
                .url("https://www.baidu.com/")
                .post(requestBody)
                .build();

        /*4.发送请求*/
        Call call = httpClient.newCall(request);
        /*5.创建请求的回调*/
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: " + e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e(TAG, "onResponse: " + response.body().string());
            }
        });

4、OKHttpClient--其他设置

    OkHttpClient httpClient = new OkHttpClient.Builder()
            //设置相应的连接池
            .connectionPool(new ConnectionPool())
            //连接超时
            .connectTimeout(15, TimeUnit.SECONDS)
            //写入超时
            .writeTimeout(15, TimeUnit.SECONDS)
            //读取超时
            .readTimeout(20, TimeUnit.SECONDS)
            .build();

5、OKHttp - 日志拦截器,重定向拦截器

//日志拦截器
public class LogInterceptor implements Interceptor {

    private static final String TAG = LogInterceptor.class.getSimpleName();

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        
        /*这样就能在请求之前打印相应的内容了*/
        Log.e("url", String.format("Sending request %s on %s %n %s", request.url(), chain.connection(), request.headers()));

        /*其实下面这个chain.proceed(request)这个方法,代表请求前和请求后*/
        return chain.proceed(request);
    }
}


//重定向拦截器
public class ResetInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        Request newRequest = new Request.Builder()
                .method("GET", null)
                .url("https://fanyi.baidu.com/translate?aldtype=16047&query=%E8%BF%9B%E5%BA%A6%0D%0A&keyfrom=baidu&smartresult=dict&lang=auto2zh#zh/en/%E9%87%8D%E7%BD%AE")
                .build();

        return chain.proceed(newRequest);
    }
}

//添加公共请求参数
public class PublicInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();

        if ("GET".equals(request.method())) {
            //GET请求的处理
            HttpUrl build = request.url().newBuilder()
                    .addQueryParameter("key1", "value1")
                    .addQueryParameter("key2", "value2")
                    .addQueryParameter("key3", "value3")
                    .addQueryParameter("key4", "value4")
                    .addQueryParameter("key5", "value5")
                    .build();

            request = request.newBuilder().url(build).build();
        } 

        return chain.proceed(request);
    }
}

POST{
        if (originalRequest.body() instanceof FormBody) {
            // 构造新的请求表单
            FormBody.Builder builder = new FormBody.Builder();

            FormBody body = (FormBody) originalRequest.body();
            //将以前的参数添加
            for (int i = 0; i < body.size(); i++) {
                builder.add(body.encodedName(i), body.encodedValue(i));
            }
            //追加新的参数
            builder.add("key1", "value1");
            builder.add("key2", "value2");
            builder.add("key3", "value3");
            builder.add("key4", "value4");
            builder.add("key5", "value5");
            //构造新的请求体
            originalRequest = originalRequest.newBuilder().post(builder.build()).build();
        }

}


6、Retrofit的基本使用

public interface NewsService {
    @GET("get?channel=头条&start=0&num=10&appkey=274ff62c9225cfa9")
    Call<News> getNews();
 
    @GET("get?channel=头条&start=0&num=10")
    Call<News> getNews(@Query("appkey") String qppKey);
  
    @GET("get?")
    Call<News> getNews(@QueryMap Map<String, String> map);
    
    //原始路径地址:http://api.jisuapi.com/train/station2s?appkey=274ff62c9225cfa9&start=杭州&end=北京&ishigh=0
    @GET("{path}/station2s?appkey=274ff62c9225cfa9&start=杭州&end=北京")
    Call<StationBean> getTrainStation(@Path("path") String path, @Query("ishigh") String ishigh);


-   @FormUrlEncoded@Multipart
-   @Field@FieldMap 添加请求参数(与@FormUrlEncoded注解配合使用)
-   @Part@PartMap 添加请求参数(与@Multipart注解配合使用)
-   @Body 封装一个对象

-   @FormUrlEncoded 纯表单形式(不包含上传文件)
-   @Multipart 表单形式(包含文件上传)

    @FormUrlEncoded @POST("train/station2s?")
    Call<StationBean> getPostTrainStation(@FieldMap Map<String, String> map);
    
    @Multipart
    @POST("/form")
    Call<ResponseBody> testLoadFile(@Part("name") String name, @Part("age") String age, @Part MultipartBody.Part file);
    
    //上面这个post使用传参以下参数
    MediaType textType = MediaType.parse("text/plain");
    RequestBody name = RequestBody.create(textType, "Carson");
    RequestBody age = RequestBody.create(textType, "24");
    RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的路径");
    MultipartBody.Part body = MultipartBody.Part.createFormData("picture", "文件名称", file);


    @Multipart
    @POST("/form")
    Call<ResponseBody> testLoadFileMore(@FieldMap Map<String, String> map, @Part MultipartBody.Part file);
    
    @Multipart
    @POST("/form")
    Call<ResponseBody> testLoadFileMore(@Part Map<String, RequestBody> map, @Part MultipartBody.Part file);


 
    @POST("train/station2s?")
    Call<StationBean> getPostTrainStationBody(@Body BodyBean bodyBean);
    //@body 封装一个对象
     BodyBean bodyBean = new BodyBean("274ff62c9225cfa9", "杭州", "北京", "0");
    Call<StationBean> postTrainStationBody = newsService.getPostTrainStationBody(bodyBean);


    // @Header
    @GET("user")
    Call<User> getUser(@Header("Authorization") String authorization)

    // @Headers
    @Headers("Authorization: authorization")
    @GET("user")
    Call<User> getUser()

    //@Url
    @GET Call<StationBean> getTrainStation(@Url String url);
  
}

        /*1.创建Retrofit的实例*/
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.jisuapi.com/news/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        /*2.定义相应的接口,获取代理对象*/
        NewsService newsService = retrofit.create(NewsService.class);
        /*3.发送请求*/
        Call<News> news = newsService.getNews();
        /*4.创建请求的回调*/
        news.enqueue(new Callback<News>() {
            @Override
            public void onResponse(Call<News> call, Response<News> response) {
                Log.e(TAG, "成功的回调: " + response.body());
                News news = response.body();
            }

            @Override
            public void onFailure(Call<News> call, Throwable t) {
                Log.e(TAG, "失败的回调: " + t.toString());
            }
        });

7.RXJava 的基本使用

public interface IWanAndroidService {
    String BASE_URL = "https://www.wanandroid.com/";
    //OkHttp+Retrofit
    //OkHttp+Retrofit+RxJava
    @GET("banner/json")
    Observable<ResponseData<List<HomeBanner>>> homeBanner();

    @POST("user/register")
    @FormUrlEncoded
    Observable<ResponseData<RegisterData>> register(@FieldMap Map<String,String> map);

}

    public Retrofit initRetrofitRxJava() {
        if (retrofit == null) {
            synchronized (NetworkManager.class) {
                if (retrofit == null) {
                    retrofit = new Retrofit.Builder()
                            .client(initClient())//选填
                            .baseUrl(IWanAndroidService.BASE_URL)//必填
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//新增网络请求适配器
                            .addConverterFactory(GsonConverterFactory.create())//选填(数据转换器,解析)
                            .build();
                }
            }
        }
        return retrofit;
    }

8、Gradle引入

dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.8.1' // 必要依赖,retrofit
    implementation 'com.squareup.retrofit2:converter-gson:2.8.1' // 必要依赖,解析json字符
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' //非必要依赖,打印日志
    
     implementation "io.reactivex.rxjava2:rxjava:2.2.6" // 必要rxjava依赖
    implementation "io.reactivex.rxjava2:rxandroid:2.1.0" // 必要rxandrroid依赖,切线程时需要用到
    ...
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0' // 必要依赖,和rxjava结合必须用到

}
   

9、工程中实际的网络请求如下:

HashMap<String, String> map = new HashMap<>();
map.put("broker_id", UserSystemTool.getUserId());
map.put("device_status", device_status);//1打开中 2后台运行 3删除
RetrofitManager.getInstance().create(DefautService.class).updateDeviceStatus(map).subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()).subscribe(new ExceptionObserver<Result>() {
    @Override
    protected void onError(ApiException e) {

    }

    @Override
    public void onSubscribe(Disposable d) {
        addSubscription(d);
    }

    @Override
    public void onNext(Result result) {

    }
});

//RetrofitManager是对Retrofit的一个简单包装
this.retrofit = (new Retrofit.Builder()).baseUrl(baseUrl).client(client).addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();

public interface DefautService {

@Headers({Constants.NEW_Y_VELUE})
@POST(ApiConstants.HOME_VERSION + "/device/updateDeviceStatus")
@FormUrlEncoded
Observable<Result> updateDeviceStatus(@FieldMap Map<String, String> params);
}