Retrofit网络框架:结合RxJava、Gson简化网络请求

​ Retrofit是一个流行的网络请求框架,可以将声明的网络请求接口通过动态代理的方式生成具体的请求,内部实际使用OkHttp进行网络请求,可以使用Gson处理请求的数据,使用RxJava进行线程的切换。下面从基础的Retrofit请求开始,依次添加OkHttp配置、Gson、RxJava简化网络请求。

接口来源:和风天气api, 网络请求key需要自己申请

例子

1、Retrofit进行基础网络请求

​ 首先创建一个基础的Retrofit实例:

    Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")             
        .build();

​ 然后声明网络请求接口:

    public interface QWeatherApi1 {    
        @GET("/v7/weather/now")    
        Call<ResponseBody> queryNow(@Query("key") String key, 
             @Query("location") String location);
    }

​ 进行网络请求:

       
    Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")           
        .build();   
    QWeatherApi1 api1 = retrofit.create(QWeatherApi1.class);  
    api1.queryNow(key, "101010100").enqueue(new Callback<ResponseBody>() {                     
        @Override        
        public void onResponse(@NotNull Call<ResponseBody> call, 
            @NotNull retrofit2.Response<ResponseBody> response) {   
            try {              
                System.out.println(response.code());    
                System.out.println("onResponse(" + response.body().string()); 
                //Retrofit内部进行了线程切换, 当前是主线程
                System.out.println(Looper.myLooper());            
            } catch (Exception e) {               
                e.printStackTrace();           
            }        
        }      

        @Override        
        public void onFailure(Call<ResponseBody> call, Throwable t) {                                
            System.out.println("onFailure(" + t.getMessage());    
        }   
    });
    

2、添加OkHttp配置:统一配置超时时间、认证等

​ 进行网络请求时需要统一配置超时时间等,同时还需要进行认证(如天气请求时统一的key), 这可以通过添加自定义的OkHttpClient来实现。

    OkHttpClient client = new OkHttpClient.Builder()        
        //连接超时时间            
        .connectTimeout(10, TimeUnit.SECONDS)     
        //读超时时间      
        .readTimeout(10, TimeUnit.SECONDS)     
        //写超时时间       
        .writeTimeout(10, TimeUnit.SECONDS)     
        .addInterceptor(new Interceptor() {         
            @NotNull           
            @Override           
            public Response intercept(@NotNull Chain chain) throws IOException {                         
                //统一添加接口需要的key               
                RealInterceptorChain realInterceptorChain = (RealInterceptorChain) chain;                 
                Request request = realInterceptorChain.request();                                        
                HttpUrl.Builder builder = request.url().newBuilder();                                     
                builder.addQueryParameter("key", key);               
                return chain.proceed(request.newBuilder().url(builder.build()).build());    
             }        
         })        
         .build();
         
     Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
          .client(client)
          .build();

​ 于是网络请求接口可以简化为:

    public interface QWeatherApi2 {   
        @GET("/v7/weather/now")    
        Call<ResponseBody> queryNow(@Query("location") String location);
    }

​ 同样地,如下进行网络请求:

    QWeatherApi2 api2 = retrofit.create(QWeatherApi2.class);
    api2.queryNow("101010100").enqueue(
       ...
    );

3、添加Gson解析

​ 网络请求回来的数据需要转成model, Retrofit提供了相关接口,可以通过Gson将请求回来的字符串转成model。

​ 添加依赖:

    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.google.code.gson:gson:2.8.7'

​ Retrofit创建时增加解析Factory:

    Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
        //使用gson进行json到model的转换
        .addConverterFactory(GsonConverterFactory.create())
        //okhttp进行数据实际请求
        .client(client)
        .build();

​ 网络请求接口可以写成:

   public interface QWeatherApi3 {
       @GET("/v7/weather/now")
       Call<NowWeatherResponse> queryNow(@Query("location") String location);
   }

​ 于是网络请求如下:

    QWeatherApi3 api3 = retrofit.create(QWeatherApi3.class);
    api3.queryNow("101010100").enqueue(new Callback<NowWeatherResponse>() {
        @Override
        public void onResponse(Call<NowWeatherResponse> call,
                            retrofit2.Response<NowWeatherResponse> response) {
                System.out.println(response.body());
        }

        @Override
        public void onFailure(Call<NowWeatherResponse> call, Throwable t) {
                System.out.println("onFailure(" + t.getMessage());
        }
     });

4、RxJava简化处理流程

​ 如果需要对返回的数据进一步处理,那么使用RxJava是一个比较好的选择。RxJava能够方便的进行上下文切换,可以将复杂、耗时的操作放到非主线程中执行,然后在主线程返回结果。

​ 引入RxJava依赖:

   implementation 'io.reactivex.rxjava2:rxjava:2.2.7'
   implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
   implementation "com.squareup.retrofit2:adapter-rxjava2:2.9.0"

​ 将RxJava配置到Retrofit中:

   Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
       //使用gson进行json到model的转换
       .addConverterFactory(GsonConverterFactory.create())
       //使用rxjava管理数据的处理与线程切换
       .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
       //okhttp进行数据实际请求
       .client(client)
       .build();

​ 然后修改网络请求接口声明:

    public interface QWeatherApi4 {
        @GET("/v7/weather/now")
        Observable<NowWeatherResponse> queryNow(@Query(value = "location") String  
           location);
    }

​ 于是网络请求如下:

    QWeatherApi4 api4 = retrofit.create(QWeatherApi4.class);
    api4.queryNow("101010100")
        .map(nowWeatherResponse -> {
            // 这里是io线程,可以进行复杂耗时的操作
            System.out.println("线程:" + Thread.currentThread());
            return nowWeatherResponse;
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .map(nowWeatherResponse -> {
            // 这里已经是主线程了,
            System.out.println("线程:" + Thread.currentThread());
            return nowWeatherResponse;
        })
        .subscribe(new Observer<NowWeatherResponse>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                list.add(d);
            }

            @Override
            public void onNext(@NonNull NowWeatherResponse weatherResponse) {
                System.out.println("onNext:" + weatherResponse);
                System.out.println("onNext(线程:" + Thread.currentThread());
            }

            @Override
            public void onError(@NonNull Throwable e) {
                System.out.println("onError:" + e.getMessage());
                e.printStackTrace();
            }

            @Override
            public void onComplete() {

            }
        });
posted @ 2021-08-07 19:15  笪笠  阅读(189)  评论(0编辑  收藏  举报