Retrofit2.0+OkHttp网络请求

一.概述

在众多的网络请求中,okhttp算口碑很不错的,再加上和Retrofit的结合,那用起来简直就是太方便了。

  1. 关于Okhttp的知识点,可以参考:https://blog.piasy.com/2016/07/11/Understand-OkHttp/  
  2. 关于Retrofit的知识点,可以参考:https://blog.csdn.net/u014695188/article/details/52985514

Retrofit的优势:

  • 首先,Retrofit使用注解方式,大大简化了我们的URL拼写形式,而且注解含义一目了然,简单易懂;
  • 其次,Retrofit使用简单,结构层次分明,每一步都能清晰的表达出之所以要使用的寓意;
  • 再者,Retrofit支持同步和异步执行,使得请求变得异常简单,只要调用enqueue/execute即可完成;
  • 最后,Retrofit更大自由度的支持我们自定义的业务逻辑,如自定义Converters。

导入依赖库:

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.okhttp3:okhttp:3.9.1'
compile 'com.squareup.okio:okio:1.13.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:converter-scalars:2.3.0'

二.使用

1.接口服务包装类RetrofitWrapper.java,负责网络请求的相关配置:

public class RetrofitWrapper {
     private static RetrofitWrapper instance;
     private Retrofit retrofit;
     private RetrofitWrapper() {
          OkHttpClient.Builder builder = new OkHttpClient.Builder();  
          /**  
           *设置缓存
           */  
          final File chachefile = new File("CacheFilePath");  
          final Cache cache = new Cache(chachefile, 1024 * 1024 * 50);//缓存文件  
          Interceptor cacheInterceptor = new Interceptor() {  
                @Override  
                public Response intercept(Chain chain) throws IOException {  
                    Request request = chain.request();  
                    if (!AppUtils.isNetworkReachable(AppAplication.getContext())) {  
                        request = request.newBuilder()  
                                .cacheControl(CacheControl.FORCE_CACHE)  
                                .build();  
                    }  
                    Response response = chain.proceed(request);  
                    if (AppUtils.isNetworkReachable(AppAplication.getContext())) {  
                        int maxAge = 0;  
                        // 有网络时 设置缓存超时时间0个小时  
                        response.newBuilder()  
                                .header("Cache-Control", "public, max-age=" + maxAge)  
                                .removeHeader("Pragma")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效  
                                .build();  
                    } else {  
                        //无网络时,设置超时为4周  
                        int maxStale = 60 * 60 * 24 * 28;  
                        response.newBuilder()  
                                .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)  
                                .removeHeader("Pragma")  
                                .build();  
                    }
                    return response;  
                }  
            };  
        builder.cache(cache).addInterceptor(cacheInterceptor);  
           
        /**  
          *公共参数
         */  
        Interceptor addQueryParameterInterceptor = new Interceptor() {  
            @Override  
            public Response intercept(Chain chain) throws IOException {  
                Request originalRequest = chain.request();  
                Request request;  
                String method = originalRequest.method();  
                Headers headers = originalRequest.headers();  
                HttpUrl modifiedUrl = originalRequest.url().newBuilder()  
                        // Provide your custom parameter here  
                        .addQueryParameter("platform", "adnroid")  
                        .addQueryParameter("version", "1.2.0")  
                        .build();  
                request = originalRequest.newBuilder().url(modifiedUrl).build();  
                return chain.proceed(request);  
            }  
        };  
        builder.addInterceptor(addQueryParameterInterceptor);

         /**  
          * 设置请求头
          */             
        Interceptor headerInterceptor = new Interceptor() {  
             
                @Override  
                public Response intercept(Chain chain) throws IOException {  
                    Request orignaRequest = chain.request();  
                    Request request = orignaRequest.newBuilder()  
                            .header("AppType", "TPOS")  
                            .header("Content-Type", "application/json")  
                            .header("Accept", "application/json")  
                            .method(orignaRequest.method(), orignaRequest.body())  
                            .build();  
       
                    return chain.proceed(request);  
                }  
            };  
         builder.addInterceptor(headerInterceptor);

         /**  
          * Log信息拦截器
          */  
            //compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'  
         if (BuildConfig.DEBUG) {  
               //log信息拦截器  
               HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();  
               httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);  
               //设置Debug Log模式  
               builder.addInterceptor(httpLoggingInterceptor);  
           }

         /**  
          * 设置cookie  
          */  
          //compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'  
        CookieManager cookieManager = new CookieManager();  
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);  
        builder.cookieJar(new JavaNetCookieJar(cookieManager));  
       /**  
        * 设置超时和重连
        */  
        //设置超时  
        builder.connectTimeout(15, TimeUnit.SECONDS);  
        builder.readTimeout(20, TimeUnit.SECONDS);  
        builder.writeTimeout(20, TimeUnit.SECONDS);  
        //错误重连  
        builder.retryOnConnectionFailure(true);  
        
         //以上设置结束,才能build(),不然设置白搭 (上面的设置都可以省略) 
        OkHttpClient okHttpClient = builder.build();  
        retrofit = new Retrofit.Builder()  
                .baseUrl(ApiUtils.BASE_URL)  
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create()) // 解析方法
                .client(okHttpClient)  
                .build();
     }
     /**
      * 单例模式
      *
      * @return
      */
     public static RetrofitWrapper getInstance() {
          if (instance == null) {
              synchronized (RetrofitWrapper.class) {
                   if (instance == null) {
                        instance = new RetrofitWrapper();
                   }
              }
          }
          return instance;
     }
     
     public <T> T create(final Class<T> service) {
        return retrofit.create(service);
    }
}

其中:设置缓存公共参数设置请求头Log信息拦截器、设置cookie、设置超时和重连如果不需要都可以省略

2.接口调用类RetrofitModel.java,负责具体调用的接口

/**
 * 接口调用类
 * @author WangBin
 * @date 2018年1月15日 下午5:29:56
 * @Description: TODO
 * @version V1.0
 */
public class RetrofitModel {
	private static RetrofitModel retrofitModel;
	private RetrofitService retrofitService;

	public static RetrofitModel getInstance() {
		if (retrofitModel == null) {
			retrofitModel = new RetrofitModel();
		}
		return retrofitModel;
	}

	private RetrofitModel() {
		retrofitService = RetrofitWrapper.getInstance().create(RetrofitService.class);
	}
	
	/**
	 * 获取用户信息(异步)
	* @param username
	* @param callback 
	*/
	public void getUser(String username, HttpCallback<User> callback) {
		Call<User> call = retrofitService.getUser(username);
		RetrofitRequest<User> request = new RetrofitRequest<User>(call);
		request.requestAsync(callback);
	}
	
	/**
	 * 获取用户信息(同步)
	* @param username
	* @return 
	*/
	public User getUserSync(String username){
		Call<User> call = retrofitService.getUser(username);
		RetrofitRequest<User> request = new RetrofitRequest<User>(call);
		return request.requestSync();
	}
}

3.接口api类RetrofitService.java

public interface RetrofitService {
     @GET("users/{username}")
     Call<User> getUser(@Path("username") String username);
     @POST("android/login.in")
     Call<String> login(@Query("loginName") String loginName, @Query("password") String password);
     
     /**
     @Path:所有在网址中的参数(URL的问号前面),如:
        http://102.10.10.132/api/Accounts/{accountId}
     @Query:URL问号后面的参数,如:
        http://102.10.10.132/api/Comments?access_token={access_token}
     @QueryMap:相当于多个@Query
     @Field:用于POST请求,提交单个数据
     @Body:相当于多个@Field,以对象的形式提交
     **/
}

4.具体的网络请求类RetrofitRequest.java

public class RetrofitRequest<T> {
     private Call<T> mCall;
     public RetrofitRequest(Call<T> call) {
          mCall = call;
     }
     /**
      * 异步请求
      *
      * @param callback
      */
     public void requestAsync(final HttpCallback<T> callback) {
          mCall.enqueue(new Callback<T>() {
              @Override
              public void onResponse(Call<T> call, Response<T> response) {
                   String path = mCall.request().url().toString();
                   if (response.isSuccessful() && response.errorBody() == null) {
                        callback.onSuccess((T) response.body(), path);
                   } else {
                        callback.onFailure(response.errorBody().toString());
                   }
              }
              @Override
              public void onFailure(Call<T> call, Throwable t) {
                   callback.onFailure(t.getMessage());
              }
          });
     }
     /**
      * 同步请求
      *
      * @return
      */
     public T requestSync() {
          Response<T> response = null;
          try {
              response = mCall.execute();
          } catch (IOException e) {
              e.printStackTrace();
          }
          return (T) response.body();
     }

5.请求回调类HttpCallback.java

public abstract class HttpCallback<T> {
     public Class<?> clazz;
     public HttpCallback() {
          Type superclass = getClass().getGenericSuperclass();
          ParameterizedType parameterizedType = null;
          if (superclass instanceof ParameterizedType) {// 参数化的泛型
              parameterizedType = (ParameterizedType) superclass;
              Type[] typeArray = parameterizedType.getActualTypeArguments();
              if (typeArray != null && typeArray.length > 0) {
                   clazz = (Class<?>) typeArray[0];
              }
          }
     }
     public abstract void onSuccess(T response, String path);
     public abstract void onFailure(String errorResponse);
}

示例中使用到的Apiutils.BASE_URL为:public static final String BASE_URL = "https://api.github.com/";

源码下载




猜你喜欢

转载自blog.csdn.net/wb1211/article/details/80179532