Okhttp3+Retrofit2+RxJava2的封装和使用&Retrofit 注解使用

1、介绍

  • Retrofit:Retrofit是Square公司开发的一款针对Android 网络请求的框架(底层默认是基于OkHttp 实现)。
  • OkHttp:也是Square公司的一款开源的网络请求库。
  • RxJava :"a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。RxJava使异步操作变得非常简单。

Retrofit 负责 请求的数据 和 请求的结果,使用 接口的方式 呈现,OkHttp 负责请求的过程,RxJava 负责异步,各种线程之间的切换。 

2、封装使用 

添加依赖库

    //网络请求okhttp3
    implementation 'com.squareup.okhttp3:okhttp:3.12.0'
    //日志的拦截器
    implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
    //Retrofit2库
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    //gson解析
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    //rxjava2库
    implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

创建RetrofitHelper类:这个类属于网络请求工具类,用于初始化Retrofit,okhttp连接的一些设置,设置请求API的baseUrl、gson解析方式等。还有通过接口对象,调用接口类中的方法也写在这个里面了。

package com.wjy.myokhttp.net;

import android.util.Log;

import com.google.gson.JsonObject;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by wjy.
 * Date: 2019/11/22
 * Time: 9:45
 * Describe: Retrofit网络请求工具类,用于初始化Retrofit,设置请求API的baseUrl、gson解析方式
 */
public class RetrofitHelper {

    private static RetrofitHelper instance = null;
    private static OkHttpClient okHttpClient;
    private ApiService apiService;

    public RetrofitHelper(OkHttpClient okHttpClient){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ApiService.BASE_URL)//服务器地址
                .addConverterFactory(GsonConverterFactory.create())//用Gson把服务端返回的json数据解析成实体
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build();//生成一个Retrofit实例
        apiService = retrofit.create(ApiService.class);//传入网络接口类,得到接口对象实例,调用接口类中的方法。
    }

    public static RetrofitHelper getInstance(){
        if (instance == null){
            instance = new RetrofitHelper(getOkhttpClient());
        }
        return instance;
    }

    //okhttp连接的一些设置
    public static OkHttpClient getOkhttpClient(){
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)//连接超时时间
                .readTimeout(20,TimeUnit.SECONDS)//读超时时间
                .writeTimeout(20,TimeUnit.SECONDS)//写超时时间
                .retryOnConnectionFailure(true)//失败重连
                .addInterceptor(loggingInterceptor)
//                .addInterceptor()//设置拦截器
                .build();
        return okHttpClient;
    }

    //日志
    static HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
        @Override
        public void log(String message) {
            //打印retrofit日志
            Log.e("RetrofitLog", "retrofitBack = " + message);
        }
    });
    //日志等级

    //=========================以下是  通过接口对象,调用接口类中的方法================================//

    public Observable<JsonObject> requestData(String url){
        return apiService.requestData(url);
    }

    public Observable<JsonObject> requestLogin_get(String username,String pwd,String regid){
        return apiService.requestLogin_get(username,pwd,regid);
    }

    public Observable<JsonObject> requestLogin_post(String username,String pwd,String regid){
        return apiService.requestLogin_post(username,pwd,regid);
    }

    public Observable<JsonObject> requestLogin_get_map(Map<String,String> params){
        return apiService.requestLogin_get_map(params);
    }

    public Observable<JsonObject> requestLogin_post_map(Map<String,String> params){
        return apiService.requestLogin_post_map(params);
    }

    public Observable<JsonObject> requestLogin_post_body(ApiService.LoginInfo loginInfo){
        return apiService.requestLogin_post_body(loginInfo);
    }

    public Observable<JsonObject> requestLogin_get_http(String username,String pwd,String regid){
        return apiService.requestLogin_get_http(username,pwd,regid);
    }

    public Observable<JsonObject> requestLogin_post_http(String username,String pwd,String regid){
        return apiService.requestLogin_post_http(username,pwd,regid);
    }

    public Observable<JsonObject> uploadImage(String tp,String code){
        return apiService.uploadImage(tp,code);
    }

}

定义接口:管理Retrofit的各种数据请求(post、get),包含请求api、请求参数,Retrofit 注解使用等。

package com.wjy.myokhttp.net;

import com.google.gson.JsonObject;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;

import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.HTTP;
import retrofit2.http.Headers;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
import retrofit2.http.Streaming;
import retrofit2.http.Url;

/**
 * Created by wjy.
 * Date: 2019/11/22
 * Time: 11:42
 * Describe: 定义接口:管理Retrofit的各种数据请求(post、get),包含请求api、请求参数
 */
public interface ApiService {

    String BASE_URL = "http://xxxxxxxxxx/";//服务器地址

    //Observable<JsonObject>  中的JsonObject可以换成对应的实体类

    /**
     * GET后面的url中可以使用自定义的变量,如 {index}、{id}进行占位 ,并使用 @Path("index") 、@Path("id") 注解为 {index} 、{id} 提供值
     * 注意:形如“?page/xxx/id/aaa”才【能】使用@Path来拼接url
     *     形如“?a=xxxx&b=xxxx&c=xxxx”的url是【不能】用@Path注解来拼接的,应该使用@Query或者@QueryMap注解
     *     @GET("?app=weather.future&weaid=1&&appkey={key}")
     * @param index
     * @param id
     * @return
     */
    @GET("page/{index}/id/{id}")
    Observable<JsonObject> requestWeather(@Path("key") int index, @Path("id") int id);

    //@Query和@QueryMap注解会把参数拼接到url后面,适用于GET请求

    //键值对形式
    @GET("?")
    Observable<JsonObject> requestWeather(@Query("app") String app,@Query("appkey") int appkey);

    //Map形式
    @GET("?")
    Observable<JsonObject> requestWeather(@QueryMap Map<String,String> params);

    //List列表形式
    @GET("?")
    Observable<JsonObject> requestWeather(@QueryMap List<String> stringList);

    //url形式
    @GET
    Observable<JsonObject> requestWeather(@Url String url);

    //无请求参数形式
    @GET("?")
    Observable<JsonObject> requestWeather();

    //==============================以上为GET请求方式===========================//


    //==============================以下为POST请求方式===========================//
    /**
     * @Field或@FieldMap做表单提交,适用于POST请求;对应POST请求,需要结合@FormUrlEncoded来使用
     * @Body会将请求参数放到请求体中,所以适用于POST请求
     * @Body标签不能和@FormUrlEncoded或@Multipart标签同时使用,会报错
     * @return
     */
    @FormUrlEncoded
    @POST("/")
    Observable<JsonObject> requestWeathers(@Field("app") String app,@Field("appkey") int appkey);

    @FormUrlEncoded
    @POST("/")
    Observable<JsonObject> requestWeathers(@FieldMap Map<String,String> params);

    /**
     * @Body实际上是将类转换成json实体作为请求体来请求网络的
     * 使用这个标签的意思是我们可以定义个实体类来封装参数,作为请求参数
     * @Body标签不能和@FormUrlEncoded或@Multipart标签同时使用,会报错
     * @param params
     * @return
     */
    @POST("/")
    Observable<JsonObject> requestWeathers(@Body RequestParams params);
    class RequestParams{
        String app;
        int appkey;
    }

    //==============================以下为HTTP请求方式===========================//
    /**
     * @HTTP请求,可配置成以上几种中的任意一种,下面就分别以一种形式来举例
     */
    //@HTTP配置get请求
    @HTTP(method = "GET", path = "?app=weather.future&&appkey=10003", hasBody = false)
    Observable<JsonObject> requestWeather1(@Query("app") String app,@Query("appkey") int appkey);

    //@HTTP配置post请求
    //1.配置POST请求必须结合@FormUrlEncoded使用,否者会报错
    //2.hasBody必须配置为true,否则报错
    @FormUrlEncoded
    @HTTP(method = "POST", path = "?", hasBody = true)
    Observable<JsonObject> requestWeather2(@Field("app") String app,@Field("appkey") int appkey);

    //==============================@Multipart 主要是与@POST结合使用做文件的上传===========================//
    @Multipart
    @POST("/")
    Observable<ResponseBody> uploadFile(@Part("description") RequestBody description, @Part MultipartBody.Part file);

    @Multipart
    @POST("/")
    Observable<ResponseBody> uploadFile(@PartMap Map<String, RequestBody> params);

    //==============================@Streaming 主要做大文件下载===========================//
    @GET
    @Streaming
    Observable<ResponseBody> downloadImage(@Url String url);


    //==============================以下为使用 Call 上传图片的几种写法===========================//
    /**
     * 上传图文
     * @param description
     * @param file
     * @return
     */
    @Multipart
    @POST("web/shrink")
    Call<ResponseBody> uploadFile1(@Part("description") RequestBody description, @Part MultipartBody.Part file);

    /**
     * 上传一张图片
     * @param file
     * @return
     */
    @Multipart
    @POST("web/shrink")
    Call<ResponseBody> uploadFile2(@Part() RequestBody file);

    /**
     * 上传一张图片 另一种写法
     * @param file
     * @return
     */
    @Multipart
    @POST()
    Call<ResponseBody> uploadFile3(@Url String url, @Part() RequestBody file);

    /**
     * 上传数量确定的多张图片
     * @param description
     * @param img1
     * @param img2
     * @param img3
     * @return
     */
    @POST("web/shrink")
    Call<ResponseBody> uploadFiles4(@Part("filename") String description,
                                   @Part("img\"; name=\"img1.png") RequestBody img1,
                                   @Part("img\"; name=\"img2.png") RequestBody img2,
                                   @Part("img\"; name=\"img3.png") RequestBody img3);

    /**
     * 上报数量不定的多张图片 版本1
     * @param params
     * @return
     */
    @Multipart
    @POST("web/shrink")
    Call<ResponseBody> uploadFile5(@PartMap Map<String, RequestBody> params);

    /**
     * 上报数量不定的多张图片 版本2
     * @param url
     * @param maps
     * @return
     */
    @Multipart
    @POST("web/shrink")
    Call<ResponseBody> uploadFile6( @Url String url, @PartMap() Map<String, RequestBody> maps);

    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&以上为常用请求方式的参考示例&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//

    //下面写几个使用测试用例
    //Url形式
    @GET
    Observable<JsonObject> requestData(@Url String url);

    //键值对形式
    @GET("?s=Platform.User.Login")
    Observable<JsonObject> requestLogin_get(@Query("username")String username,@Query("pwd") String pwd,@Query("regid") String regid);

    @POST("/?s=Platform.User.Login")
    @FormUrlEncoded
    Observable<JsonObject> requestLogin_post(@Field("username") String username,@Field("pwd") String pwd,@Field("regid") String regid);

    //GET请求的Map形式
    @GET("?s=Platform.User.Login")
    Observable<JsonObject> requestLogin_get_map(@QueryMap Map<String,String> params);

    //POST请求的Map形式
    @FormUrlEncoded
    @POST("/?s=Platform.User.Login")
    Observable<JsonObject> requestLogin_post_map(@FieldMap Map<String,String> params);

    //@Body实际上是将类转换成json实体作为请求体来请求网络,目前没找到可以接受json格式的请求体作为参数的网络,因此这里这是从形式说明怎么使用,这是没有问题
    @POST("/?s=Platform.User.Login")
    Observable<JsonObject> requestLogin_post_body(@Body LoginInfo loginInfo);
    class LoginInfo{
        public String username;
        public String pwd;
        public String regid;
    }

    //@HTTP配置get请求
    @HTTP(method = "GET", path = "?s=Platform.User.Login", hasBody = false)
    Observable<JsonObject> requestLogin_get_http(@Query("username") String username,@Query("pwd") String pwd,@Query("regid") String regid);

    //@HTTP配置post请求
    //1.配置POST请求必须结合@FormUrlEncoded使用,否者会报错
    //2.hasBody必须配置为true,否则报错
    @FormUrlEncoded
    @HTTP(method = "POST", path = "/?s=Platform.User.Login", hasBody = true)
    Observable<JsonObject> requestLogin_post_http(@Field("username") String username,@Field("pwd") String pwd,@Field("regid") String regid);

    /**
     * 上传一张图片
     */
    @POST("/?s=Platform.UpImg.Img")
    @FormUrlEncoded
    Observable<JsonObject> uploadImage(@Field("tp") String tp,@Field("code") String code);


    @Headers("Content-Type: application/json")
    @POST("/")
    Observable<JsonObject> requestTest(@Body HandlerModel handlerModel);
    class HandlerModel{
        public String Action;
        public Object[] Param;
    }
}

在Activity中的使用:


    /**
     * get的Url请求
     */
    private void requestGet_Url(){
        RetrofitHelper.getInstance()
                .requestData("http://59.110.162.30/app_updater_version.json")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * get请求
     */
    private void requestLogin_get(){
        RetrofitHelper.getInstance()
                .requestLogin_get("13801234567","123456","100d8559092c7ef7d5a")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * post请求
     */
    private void requestLogin_post(){
        RetrofitHelper.getInstance()
                .requestLogin_post("13801234567","123456","100d8559092c7ef7d5a")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * get请求Map
     */
    private void requestLogin_get_map(){
        Map<String,String> params = new HashMap<>();
        params.put("username","13801234567");
        params.put("pwd","123456");
        params.put("regid","100d8559092c7ef7d5a");
        RetrofitHelper.getInstance()
                .requestLogin_get_map(params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * post请求  Map
     */
    private void requestLogin_post_map(){
        Map<String,String> params = new HashMap<>();
        params.put("username","13801234567");
        params.put("pwd","123456");
        params.put("regid","100d8559092c7ef7d5a");
        RetrofitHelper.getInstance()
                .requestLogin_post_map(params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * post请求  Body
     * @Body实际上是将类转换成json实体作为请求体来请求网络,目前没找到可以接受json格式的请求体作为参数的网络,因此这里这是从形式说明怎么使用,这是没有问题
     */
    private void requestLogin_post_body(){
        ApiService.LoginInfo loginInfo = new ApiService.LoginInfo();
        loginInfo.username = "13801234567";
        loginInfo.pwd = "123456";
        loginInfo.regid = "100d8559092c7ef7d5a";
        RetrofitHelper.getInstance()
                .requestLogin_post_body(loginInfo)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * get请求  Http
     */
    private void requestLogin_get_http(){
        RetrofitHelper.getInstance()
                .requestLogin_get_http("13801234567","123456","100d8559092c7ef7d5a")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * post请求  Http
     */
    private void requestLogin_post_http(){
        RetrofitHelper.getInstance()
                .requestLogin_post_http("13801234567","123456","100d8559092c7ef7d5a")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

    /**
     * 图片上传
     */
    private void requestuploadImage(){
        String stream = null;
        String filePath = "/sdcard/UVCCamera/img_goods.png";//图片地址
        stream = Base64StringTool.getcomImageBase64(Base64StringTool.getSmallBitmap(filePath));
        if (TextUtils.isEmpty(stream)) {
            Toast.makeText(MainActivity.this,"图片上传失败!",Toast.LENGTH_SHORT).show();
            return;
        }
        RetrofitHelper.getInstance()
                .uploadImage("dev",stream)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new NetSubscribe<JsonObject>(MainActivity.this) {
                    @Override
                    public void onNext(JsonObject value) {
                        Log.e("MainActivity","onNext  value="+value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity","onError  e="+e);
                        e.printStackTrace();
                    }
                });
    }

感觉下面两篇博文也不错,谢谢:

Android版&Kotlin版RxJava2+Retrofit2+OkHttp3的基础、封装和项目中的使用

Retrofit 注解学习 @GET @POST @Query @QueryMap @Field @FieldMap @Body ... 

下面附上git源码地址:https://gitee.com/AlaYu/okhttp3_retrofit2_rxjava2#okhttp3retrofit2rxjava2 

发布了92 篇原创文章 · 获赞 38 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/u013184970/article/details/103287823