美文网首页android
Retrofit 2.0 配置篇

Retrofit 2.0 配置篇

作者: 敲代码的本愿 | 来源:发表于2016-10-12 21:22 被阅读942次

    获取实例

    获取 OkHttpClient.Builder 对象:

    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    

    Log信息拦截器

    Debug模式查看网络请求、打印Log信息,发布时不需要Log

    添加依赖

    项目的build.gradle添加:

    compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
    

    设置拦截器

    if(BuildConfig.DEBUG){
        //Log信息拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        //设置Log
        builder.addInterceptor(loggingInterceptor);
    }
    

    缓存机制

    无网络时,也能显示数据。

    File cacheFile = new File(MyApplication.getContext().getExternalCacheDir(), "DemoCache");
    Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
    Interceptor cacheInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!AppUtils.networkIsAvailable(MyApplication.getContext())) {
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_CACHE)
                        .build();
            }
            Response response = chain.proceed(request);
            if (AppUtils.networkIsAvailable(MyApplication.getContext())) {
                int maxAge = 0;
                // 有网络时 设置缓存超时时间0个小时
                response.newBuilder()
                        .header("Cache-Control", "public, max-age=" + maxAge)
                        .removeHeader("Demo")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
                        .build();
            } else {
                // 无网络时,设置超时为4周
                int maxStale = 60 * 60 * 24 * 28;
                    response.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .removeHeader("nyn")
                        .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", "android")
                    .addQueryParameter("version", "1.0.0")              
                    .build();
            request = originalRequest.newBuilder().url(modifiedUrl).build();
            return chain.proceed(request);
        }
    };
    builder.addInterceptor(addQueryParameterInterceptor);
    

    请求头

    以下为初始配置方式添加请求头,另一种为定义接口方式,详见注解篇 @Headers

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

    cookie

    服务端可能需要保持请求是同一个 cookie ,看需求。

    添加依赖

    项目的build.gradle添加:

    compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
    

    设置cookie

    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);
    

    设置Retrofit

    OkHttpClient okHttpClient = builder.build();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(ApiStores.API_SERVER_URL)
            //设置 Json 转换器
            .addConverterFactory(GsonConverterFactory.create())
            //RxJava 适配器
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(okHttpClient)
            .build();
    

    Json转换器

    默认情况,Retrofit 只能反序列化 Http bodiesOkHttpResponseBody 且只能接受它为 @Body 的类型。

    Retrofit 2.0 支持多种解析方式来解析响应数据:

    • Gson::com.squareup.retrofit2:converter-gson
    • Jacksoncom.squareup.retrofit2:converter-jackson
    • Moshicom.squareup.retrofit2:converter-moshi
    • Protobufcom.squareup.retrofit2:converter-protobuf
    • Wirecom.squareup.retrofit2:converter-wire
    • Simple XMLcom.squareup.retrofit2:converter-simplexml
    • Scalars (primitives, boxed, and String):com.squareup.retrofit2:converter-scalars

    自定义转换器
    继承Converter.Factory class
    http://simple.sourceforge.net/

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://api.nuuneoi.com/base/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    

    RxJava

    除了提供 Callback 形式的API,还有RxJava版本的 Observable 形式API

    添加依赖

    compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta3'
    compile 'io.reactivex:rxandroid:1.0.1'
    

    设置

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://api.nuuneoi.com/base/")
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
    

    栗子一:获取一个User对象的接口

    Callback 方式:

    //定义请求
    @GET("/user")
    public void getUser(@Query("userId") String userId, Callback<User> callback);
    
    //使用
    getUser(userId, new Callback<User>() {
        @Override
        public void success(User user) {
            userView.setUser(user);
        }
    
        @Override
        public void failure(RetrofitError error) {
            // Error handling
            ...
        }
    };
    

    Rxjava 方式:

    //定义请求
    @GET("/user")
    public Observable<User> getUser(@Query("userId") String userId);
    
    //使用
    getUser(userId)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<User>() {
                @Override
                public void onNext(User user) {
                    userView.setUser(user);
                }
    
                @Override
                public void onCompleted() {
                }
    
                @Override
                public void onError(Throwable error) {
                    // Error handling
                    ...
                }
            });
    

    栗子二:获取到的 User 不直接显示,先与数据库中的数据比对修正后再显示

    Callback 方式:

    getUser(userId, new Callback<User>() {
        @Override
        public void success(User user) {
            processUser(user); // 尝试修正 User 数据
            userView.setUser(user);
        }
    
        @Override
        public void failure(RetrofitError error) {
            // Error handling
            ...
        }
    };
    

    注意:数据库操作属耗时操作,所以要避免在主线程中操作数据库。

    //修改后
    getUser(userId, new Callback<User>() {
        @Override
        public void success(User user) {
            new Thread() {
                @Override
                public void run() {
                    processUser(user); // 尝试修正 User 数据
                    runOnUiThread(new Runnable() { // 切回 UI 线程
                        @Override
                        public void run() {
                            userView.setUser(user);
                        }
                    });
                }
            }).start();
        }
    
        @Override
        public void failure(RetrofitError error) {
            // Error handling
            ...
        }
    };
    

    Rxjava 方式:

    getUser(userId)
            .doOnNext(new Action1<User>() {
                @Override
                public void call(User user) {
                    processUser(user);
                })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<User>() {
                @Override
                public void onNext(User user) {
                    userView.setUser(user);
                }
    
                @Override
                public void onCompleted() {
                }
    
                @Override
                public void onError(Throwable error) {
                    // Error handling
                    ...
                }
            });
    

    栗子三:/user 接口不能直接访问,需要填入在线获取的 token

    Callback 方式:可以嵌套Callback

    @GET("/token")
    public void getToken(Callback<String> callback);
    
    @GET("/user")
    public void getUser(@Query("token") String token, @Query("userId") String userId, Callback<User> callback);
    
    ...
    
    getToken(new Callback<String>() {
        @Override
        public void success(String token) {
            getUser(token, userId, new Callback<User>() {
                @Override
                public void success(User user) {
                    userView.setUser(user);
                }
    
                @Override
                public void failure(RetrofitError error) {
                    // Error handling
                    ...
                }
            };
        }
    
        @Override
        public void failure(RetrofitError error) {
        // Error handling
            ...
        }
    });
    

    Rxjava 方式:

    @GET("/token")
    public Observable<String> getToken();
        
    @GET("/user")
    public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId);
        
    ...
        
    getToken()
            .flatMap(new Func1<String, Observable<User>>() {
                @Override
                public Observable<User> onNext(String token) {
                    return getUser(token, userId);
                })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<User>() {
                @Override
                public void onNext(User user) {
                    userView.setUser(user);
                }
        
                @Override
                public void onCompleted() {
                }
        
                @Override
                public void onError(Throwable error) {
                    // Error handling
                    ...
                }
            });
    

    完整配置

    public class AppClient {
        public static Retrofit retrofit = null;
    
        public static Retrofit retrofit() {
            if (retrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            /**
            *   设置缓存
            */
    
            /**
            *  公共参数
            */
    
            /**
            * 设置头
            */           
        
            /**
            * Log信息拦截器
            */
        
            /**
            * 设置cookie
            */
        
            /**
            * 设置超时和重连
            */
        
            //以上设置完成
            OkHttpClient okHttpClient = builder.build();
        
            retrofit = new Retrofit.Builder()
                    .baseUrl(ApiStores.API_SERVER_URL)
                    //设置 Json 转换器
                    .addConverterFactory(GsonConverterFactory.create())
                    //RxJava 适配器
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(okHttpClient)
                    .build();
            }
            return retrofit;
        }
    }
    

    混淆配置

    # Platform calls Class.forName on types which do not exist on Android to determine platform.
    -dontnote retrofit2.Platform
    # Platform used when running on RoboVM on iOS. Will not be used at runtime.
    -dontnote retrofit2.Platform$IOS$MainThreadExecutor
    # Platform used when running on Java 8 VMs. Will not be used at runtime.
    -dontwarn retrofit2.Platform$Java8
    # Retain generic type information for use by reflection by converters and adapters.
    -keepattributes Signature
    # Retain declared checked exceptions for use by a Proxy instance.
    -keepattributes Exceptions
    

    相关文章

      网友评论

      本文标题:Retrofit 2.0 配置篇

      本文链接:https://www.haomeiwen.com/subject/zboiyttx.html