Retrofit2+OkHttp3+RxJave 三剑客解决网络问题

1 篇文章 0 订阅
1 篇文章 0 订阅



public class RetrofitManager {





    /**
     * 需要的引用
     *   retrofit2 + okhttp3 引用
     *    compile 'com.android.support.constraint:constraint-layout:1.0.2'
     *    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
     *    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
     *    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
     *    compile 'com.squareup.retrofit2:converter-scalars:2.0.0-beta4'
     *    compile 'com.squareup.okhttp3:okhttp:3.2.0'
     *    compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
     *    compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
     *
     *   rxjava引用
     *    compile 'io.reactivex:rxandroid:1.1.0'
     *    compile 'io.reactivex:rxjava:1.1.0'
     *
     * 拼url 的资料            @see{     http://blog.csdn.net/linzhenxiang123/article/details/52593971  }
     *
     * cookie持久化解决方案    @see{     https://github.com/franmontiel/PersistentCookieJar      }
     *
     */

    private static final long TIMEOUT = 1000 * 30;
    private static final String BASE_URL="http://gank.io/api/";

    private static RetrofitManager retrofitManager;
    protected ApiService apiService;


    private RetrofitManager(Context context) {
        OkHttpClient client = initOkHttpClient(context);
        Retrofit retrofit = initRetrofit(client);
        apiService = retrofit.create(ApiService.class);
    }

    /**
     * 初始化okhttp
     *
     * @param context
     * @return
     */
    private OkHttpClient initOkHttpClient(Context context) {
        //新建一个文件用来缓存网络请求
        File cacheDirectory = new File(context.getCacheDir().getAbsolutePath(), "HttpCache");
        ClearableCookieJar cookieJar =
                new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
        //实例化一个OkHttpClient.Builder
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(TIMEOUT, TimeUnit.SECONDS)//设置连接超时
                .readTimeout(TIMEOUT, TimeUnit.SECONDS)//设置从主机读信息超时
                .writeTimeout(TIMEOUT, TimeUnit.SECONDS)//设置写信息超时
                .retryOnConnectionFailure(true)///如果连接失败,尝试重连
                .cache(new Cache(cacheDirectory, 10 * 1024 * 1024))//设置缓存文件
                .addInterceptor(initInterceptor())//设置okhttp拦截器,这样做的好处是可以为你的每一个retrofit2的网络请求都增加相同的head头信息,而不用每一个请求都写头信息
                .addInterceptor(initLogInterceptor())//打印日志
                .cookieJar(cookieJar)
                .build();
        return client;
    }

    /**
     * 初始化http拦截器
     *
     * @return
     */
    private Interceptor initInterceptor() {
        BasicParamsInterceptor builder =new BasicParamsInterceptor.Builder()
                .addHeaderParam("Content-Type", "application/json; charset=UTF-8")
                .addHeaderParam("Connection", "keep-alive")
                .addHeaderParam("Accept", "*/*")
                .addHeaderParam("Cache-Control", String.format("public, max-age=%d", 60))
                .build();
        return builder;
    }

    private Interceptor initLogInterceptor(){
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.i("info", "请求参数:" + message);
            }
        });
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return  interceptor;
    }


    /**
     * 初始化  Retrofit
     * @param client
     * @return
     */
    private Retrofit initRetrofit(OkHttpClient client) {
        Retrofit builder = new Retrofit.Builder()
                .client(client)//设置 HTTP Client  用于请求的连接
                .addConverterFactory(ScalarsConverterFactory.create())//如果网络访问返回的字符串,而不是json数据格式,要使用下面的转换器
                .addConverterFactory(GsonConverterFactory.create())//如果网络访问返回的是json字符串,使用gson转换器
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//此处顺序不能和上面对调,否则不能同时兼容普通字符串和Json格式字符串  为了支持rxjava,需要添加下面这个把 Retrofit 转成RxJava可用的适配类
                .baseUrl(BASE_URL)//请求的父目录
                .build();
        return builder;
    }


    public static RetrofitManager getInstance(Context context) {
        if (retrofitManager == null) {
            synchronized (RetrofitManager.class) {
                if (retrofitManager == null)
                    retrofitManager = new RetrofitManager(context);
            }
        }
        return retrofitManager;
    }

    public ApiService getApiService(){
        return apiService;
    }

}


public abstract class ApiCallBack<T> extends Subscriber<T> {

    protected abstract void onSuccess(T t);

    protected  abstract void onFailure();

    protected  abstract void onFinish();


    @Override
    public void onCompleted() {
        onFinish();
    }

    @Override
    public void onError(Throwable e) {
        if(e instanceof HttpException){
            HttpException exception = (HttpException)e;
            int code = exception.response().code();
            Log.i("info","code:"+code);
        }else if (e instanceof JsonParseException
                || e instanceof JSONException) {
            Log.i("info","code:解析错误");
        } else if (e instanceof ConnectException) {
            Log.i("info","code:连接失败");
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            Log.i("info","code:证书验证失败");
        } else {
            Log.i("info","code:未知错误");
        }
        onFailure();
    }

    @Override
    public void onNext(T t) {
        onSuccess(t);
    }
}


public class BasicParamsInterceptor implements Interceptor {

    Map<String, String> queryParamsMap = new HashMap<>();
    Map<String, String> paramsMap = new HashMap<>();
    Map<String, String> headerParamsMap = new HashMap<>();
    List<String> headerLinesList = new ArrayList<>();

    private BasicParamsInterceptor() {

    }

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();
        Request.Builder requestBuilder = request.newBuilder();

        // process header params inject
        Headers.Builder headerBuilder = request.headers().newBuilder();
        if (headerParamsMap.size() > 0) {
            Iterator iterator = headerParamsMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
            }
        }

        if (headerLinesList.size() > 0) {
            for (String line: headerLinesList) {
                headerBuilder.add(line);
            }
        }

        requestBuilder.headers(headerBuilder.build());
        // process header params end




        // process queryParams inject whatever it's GET or POST
        if (queryParamsMap.size() > 0) {
            injectParamsIntoUrl(request, requestBuilder, queryParamsMap);
        }
        // process header params end




        // process post body inject
        if (request.method().equals("POST") && request.body().contentType().subtype().equals("x-www-form-urlencoded")) {
            FormBody.Builder formBodyBuilder = new FormBody.Builder();
            if (paramsMap.size() > 0) {
                Iterator iterator = paramsMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry entry = (Map.Entry) iterator.next();
                    formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue());
                }
            }
            RequestBody formBody = formBodyBuilder.build();
            String postBodyString = bodyToString(request.body());
            postBodyString += ((postBodyString.length() > 0) ? "&" : "") +  bodyToString(formBody);
            requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
        } else {    // can't inject into body, then inject into url
            injectParamsIntoUrl(request, requestBuilder, paramsMap);
        }

        request = requestBuilder.build();
        return chain.proceed(request);
    }

    // func to inject params into url
    private void injectParamsIntoUrl(Request request, Request.Builder requestBuilder, Map<String, String> paramsMap) {
        HttpUrl.Builder httpUrlBuilder = request.url().newBuilder();
        if (paramsMap.size() > 0) {
            Iterator iterator = paramsMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                httpUrlBuilder.addQueryParameter((String) entry.getKey(), (String) entry.getValue());
            }
        }

        requestBuilder.url(httpUrlBuilder.build());
    }

    private static String bodyToString(final RequestBody request){
        try {
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if(copy != null)
                copy.writeTo(buffer);
            else
                return "";
            return buffer.readUtf8();
        }
        catch (final IOException e) {
            return "did not work";
        }
    }

    public static class Builder {

        BasicParamsInterceptor interceptor;

        public Builder() {
            interceptor = new BasicParamsInterceptor();
        }

        public Builder addParam(String key, String value) {
            interceptor.paramsMap.put(key, value);
            return this;
        }

        public Builder addParamsMap(Map<String, String> paramsMap) {
            interceptor.paramsMap.putAll(paramsMap);
            return this;
        }

        public Builder addHeaderParam(String key, String value) {
            interceptor.headerParamsMap.put(key, value);
            return this;
        }

        public Builder addHeaderParamsMap(Map<String, String> headerParamsMap) {
            interceptor.headerParamsMap.putAll(headerParamsMap);
            return this;
        }

        public Builder addHeaderLine(String headerLine) {
            int index = headerLine.indexOf(":");
            if (index == -1) {
                throw new IllegalArgumentException("Unexpected header: " + headerLine);
            }
            interceptor.headerLinesList.add(headerLine);
            return this;
        }

        public Builder addHeaderLinesList(List<String> headerLinesList) {
            for (String headerLine: headerLinesList) {
                int index = headerLine.indexOf(":");
                if (index == -1) {
                    throw new IllegalArgumentException("Unexpected header: " + headerLine);
                }
                interceptor.headerLinesList.add(headerLine);
            }
            return this;
        }

        public Builder addQueryParam(String key, String value) {
            interceptor.queryParamsMap.put(key, value);
            return this;
        }

        public Builder addQueryParamsMap(Map<String, String> queryParamsMap) {
            interceptor.queryParamsMap.putAll(queryParamsMap);
            return this;
        }

        public BasicParamsInterceptor build() {
            return interceptor;
        }

    }
}

public interface ApiService {


//    @POST("site/search")
//    Observable<SearchResult> search(@Body SearchRequestBody searchRequestBody);
    /**
     * 获取App启动页信息
     * @return
     */
    @GET("json/page/app-data/info.json?v=3.0.1&os=1&ver=4")
    Observable<AppStart> getAppStartInfo();

    // 随机数据
    @GET("random/data/{type}/{count}")
    Observable<GankModel> loadRandomData(@Path("type")String type , @Path("count") int count);
}


public class BaseActivity extends AppCompatActivity {
    private CompositeSubscription compositeSubscription;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        compositeSubscription = new CompositeSubscription();
    }

    @Override
    protected void onDestroy() {
        if (compositeSubscription.hasSubscriptions()) {
            compositeSubscription.unsubscribe();
        }
        super.onDestroy();
    }

    public void doHttpRequest(Observable observable, Subscriber subscriber) {
        compositeSubscription.add(
                observable.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(subscriber));
    }
}

public class GankModel {


    private boolean error;
    List<Results> results;

    public boolean getError() {
        return error;
    }

    public void setError(boolean error) {
        this.error = error;
    }

    public List<Results> getResults() {
        return results;
    }

    public void setResults(List<Results> results) {
        this.results = results;
    }

    public static class Results {
        private String _id;
        private String createdAt;
        private String desc;
        private String publishedAt;
        private String type;
        private String url;
        private boolean used;
        private String who;

        public String get_id() {
            return _id;
        }

        public void set_id(String _id) {
            this._id = _id;
        }

        public String getCreatedAt() {
            return createdAt;
        }

        public void setCreatedAt(String createdAt) {
            this.createdAt = createdAt;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }

        public String getPublishedAt() {
            return publishedAt;
        }

        public void setPublishedAt(String publishedAt) {
            this.publishedAt = publishedAt;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public boolean isUsed() {
            return used;
        }

        public void setUsed(boolean used) {
            this.used = used;
        }

        public String getWho() {
            return who;
        }

        public void setWho(String who) {
            this.who = who;
        }

        @Override
        public String toString() {
            return "Results{" +
                    "_id='" + _id + '\'' +
                    ", createdAt='" + createdAt + '\'' +
                    ", desc='" + desc + '\'' +
                    ", publishedAt='" + publishedAt + '\'' +
                    ", type='" + type + '\'' +
                    ", url='" + url + '\'' +
                    ", used=" + used +
                    ", who='" + who + '\'' +
                    '}';
        }
    }
}

调用方法


doHttpRequest(RetrofitManager.getInstance(this).getApiService().loadRandomData("福利", 20), new ApiCallBack<GankModel>() {
    @Override
    protected void onSuccess(GankModel gankModels) {
            Log.i("info","gankModel--->"+gankModels.getError());
    }

    @Override
    protected void onFailure() {
        Log.i("info","------------------onFailure----------------");
    }

    @Override
    protected void onFinish() {
        Log.i("info","------------------onFinish----------------");
    }

    @Override
    public void onStart() {

    }
});


资源地址:       http://download.csdn.net/detail/qq_22256027/9902831



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值