Retrofit的簡單封裝--更方便的配置okhttp

前言:

Retrofit作爲簡化HTTP請求的庫,已經運行多年,2.0版本依然不辱使命的在做這些事情。不過2.0版本修復了一些長期影響開發者的設計,還加入了前所未有的強大特性。在NYC2015的這一個分享中,Jake Wharton的演講涵蓋了所有Retrofit2.0的新特性,全面介紹了Retrofit2.0工作原理。看我

首先給出官網源碼(點我)和基礎使用方法(點我

初始配置就看官網了,廢話不多說,開始封裝:

一、Api請求網絡配置

(1)添加所需要的配置:

public class NetConfig {
    File RESPONSE_CACHE;//緩存文件
    int RESPONSE_CACHE_SIZE;//緩存文件大小
    int CONNET_TIMEOUT;//連接超時
    int READ_TIMEOUT;//讀取新鏈接超時
    int MAX_CACHE_AGE;//從文檔被訪問後的存活時間
    Context context;

    public NetConfig(File RESPONSE_CACHE,int RESPONSE_CACHE_SIZE,int CONNET_TIMEOUT,int READ_TIMEOUT,int MAX_CACHE_AGE,Context context){
        this.RESPONSE_CACHE = RESPONSE_CACHE;
        this.RESPONSE_CACHE_SIZE = RESPONSE_CACHE_SIZE;
        this.CONNET_TIMEOUT = CONNET_TIMEOUT;
        this.READ_TIMEOUT = READ_TIMEOUT;
        this.MAX_CACHE_AGE = MAX_CACHE_AGE;
        this.context = context;
    }
}

(2)通過構建者模式設置默認初始網絡配置

public class NetConfigBuilder {

    private File response_cache;
    private int response_cache_size = 5 * 1024 * 1024;
    private int connect_timeout = 8 * 1000;
    private int read_timeout = 5 * 1000;
    private Context appContext;
    private int maxCacheAge = 0;

    /**
     * request cache-control
     */
    public NetConfigBuilder maxCacheAge(int maxCacheAge) {
        this.maxCacheAge = maxCacheAge;
        return this;
    }

    /**
     * local cache dir
     */
    public NetConfigBuilder responseCacheDir(File response_cache) {
        this.response_cache = response_cache;
        return this;
    }

    /**
     * local cache size
     */
    public NetConfigBuilder responseCacheSize(int response_cache_size) {
        this.response_cache_size = response_cache_size;
        return this;
    }

    /**
     * readTime
     *
     * @param connect_timeout millisecond
     */
    public NetConfigBuilder connectionTimeout(int connect_timeout) {
        this.connect_timeout = connect_timeout;
        return this;
    }

    /**
     * timeout
     *
     * @param read_timeout millisecond
     */
    public NetConfigBuilder readTimeout(int read_timeout) {
        this.read_timeout = read_timeout;
        return this;
    }

    /**
     * must set Context
     */
    public NetConfigBuilder context(Context app) {
        this.appContext = app.getApplicationContext();
        return this;
    }

    public NetConfig createNetConfig() {
        return new NetConfig(response_cache, response_cache_size, connect_timeout, read_timeout, maxCacheAge, appContext);
    }
}

(3)在全局Application中初始化自己配置:

public abstract class NetUtils {
    public static NetConfig netConfig;

    public static void setNetConfig(NetConfig netConfig){
        NetUtils.netConfig = netConfig;
    }

    public static <T> T createApi(Class<T> clazz, String host){
        if(netConfig.context == null)
            throw new IllegalArgumentException("must be set Context,use NetUtils.setNetConfig() at once");
        return RetrofitUtils.createApi(netConfig.context,clazz,host);
    }
}
public class App extends Application{
    private static Context context;

    //獲取全局context
    public static Context getContext(){
        return context;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();

        /**
         * net config
         */
        final NetConfig netConfig = new NetConfigBuilder()
                .context(this)
                .responseCacheDir(new File(context.getCacheDir(),"mycache"))
                .responseCacheSize(1024 * 1024 * 100)
                .readTimeout(2000)
                .createNetConfig();
        NetUtils.setNetConfig(netConfig);
    }
}

二、配置Retrofit和OkHttp

(1)OkHttpUtils可通過設置攔截器等okhttp的初始配置:

public class OkHttpUtils {

    private final static File RESPONSE_CACHE = NetUtils.netConfig.RESPONSE_CACHE;
    private final static int RESPONSE_CACHE_SIZE = NetUtils.netConfig.RESPONSE_CACHE_SIZE;
    private final static int CONNECT_TIMEOUT = NetUtils.netConfig.CONNET_TIMEOUT;
    private final static int READ_TIMEOUT = NetUtils.netConfig.READ_TIMEOUT;
    private static OkHttpClient singleton;

    static OkHttpClient getSingleton(final Context context){
        if(singleton == null){
            synchronized (OkHttpUtils.class){
                if(singleton == null){
                    singleton = new OkHttpClient().newBuilder()
                            .cache(new Cache(RESPONSE_CACHE != null?RESPONSE_CACHE:new File(context.getCacheDir(),"defalut_cache"),RESPONSE_CACHE_SIZE))
                            .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
                            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
                            .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
                            .build();
                }
            }
        }
        return singleton;
    }

    private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            Response originalResponse = chain.proceed(chain.request());
            if (NetUtil.isNetworkAvailable(App.getContext())) {
                int maxAge = 60; // 在線緩存在1分鐘內可讀取
                return originalResponse.newBuilder()
                        .header("Cache-Control", "public, max-age=" + maxAge)
                        .build();
            } else {
                int maxStale = 60 * 60 * 24 * 28; // 離線時緩存保存4周
                return originalResponse.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .build();
            }
        }
    };
}

(2)RetrofitUtilsze則初始化Retrofit2配置:

public class RetrofitUtils {

    private static Retrofit singleton;

    static <T> T createApi(Context context, Class<T> clazz, String host){
        if(singleton == null){
            synchronized (RetrofitUtils.class){
                if(singleton == null){
                    singleton = new Retrofit.Builder()
                            .baseUrl(host)
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(OkHttpUtils.getSingleton(context))
                            .build();
                }
            }
        }


        return singleton.create(clazz);
    }

}

三、使用

(1)定義接口,封裝訪問的方法:

public interface AllApi {

    @GET("txapi/mvtp/meinv")
    Call<GrilBean> getGril(@Header("apikey") String key, @Query("num") int num);

}

(2)調用訪問的方法:

public class ApiUser {
    public static AllApi get(){
        return NetUtils.createApi(AllApi.class, Constant.url);
    }
}

Call<GrilBean> call = ApiUser.get().getGril(Constant.AES_KEY,12);
call.enqueue(new Callback<GrilBean>() {
    @Override
    public void onResponse(Call<GrilBean> call, Response<GrilBean> response) {
        if (response.isSuccessful()) {
            GrilBean result = response.body();
            //具體操作......
        }
    }

    @Override
    public void onFailure(Call<GrilBean> call, Throwable t) {

    }
});

四、總結

上面只是給出個初始的封裝,後續可根據其添加所需配置,源碼請看這裏

總之,Retrofit解耦的很徹底:比方說通過註解來配置請求參數,通過工廠來生成CallAdapter,Converter,你可以使用不同的請求適配器(CallAdapter),比方說RxJava,Java8,Guava。你可以使用不同的反序列化工具(Converter),比方說son,protobuff,xml,moshi等等。所以非常推薦使用。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章