zoukankan      html  css  js  c++  java
  • 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() {
    
                }
            });
    
  • 相关阅读:
    DB-概念-同义词:同义词/Synonym
    DB-概念-数据库:数据库/Database
    DB:目录
    信息安全-OAuth2.0:NuGetFromMicrosoft
    资源-DotNet-站点:DotNet 站点列表
    Nuget-Swagger-Swashbuckle:Swashbuckle
    Nuget-Doc:Nuget 简介
    Nuget-Doc:NuGet 介绍
    术语-Portal:Portal(Web站点)
    cocos2d-html5模板分析
  • 原文地址:https://www.cnblogs.com/wushengwuxi/p/15112822.html
Copyright © 2011-2022 走看看