OKHTTP

作者: 要学的东西太多了 | 来源:发表于2018-10-31 10:22 被阅读0次

    OKHTTP流程:

    • 初始化OkHttpClient对象,在构造方法里面用默认的Builder对象进行初始化,也可以用builder来构建,builder的cache可以为OKHttp指定缓存方式,框架提供了默认的Cache对象,只需要传入缓存文件和大小即可。
    • 初始化request对象,设置url、请求方式、请求数据、请求头等;
    • okHttpClient.newCall(request).enqueue(callback)方法,实际上是realcall对象执行enqueue方法,然后往任务队列里面插入asynccall(继承NamedRunnable类,它实现了runnable接口)任务,并由线程池去执行asynccall,调用其execute方法,通过
    • getResponseWithInterceptorChain()方法拿到结果并进行回调。这里是调用了一系列的拦截链,可以自定义ResponseBody并添加NetworkInterceptor来实现自己的处理逻辑。

    OKHTTP一般需要自行封装,全局用一个对象,且需要用到handler来更新UI,因为回调都在子线程中。

    常见用法如下:

    public class HttpUtils {
        private static volatile HttpUtils h;
        private static final int TIME_OUT = 30;
        private OkHttpClient mClient;
        private Gson mGson;
        private IProgressUpdate mIProgressUpdate;
        private static final String CACHE_PATH = BaseApp.getInstance().getApplicationContext().getFilesDir().getParent() + "/httpCache/";
        private HttpUtils(){
            if (h != null) {
                throw new RuntimeException("禁止反射");
            }
            mGson = new Gson();
            initClient();
        }
    
        public static HttpUtils getInstance(){
            if(h==null){
                synchronized (HttpUtils.class){
                    if(h==null){
                        h = new HttpUtils();
                    }
                }
            }
            return h;
        }
    
        public void setIProgressUpdate(IProgressUpdate IProgressUpdate) {
            mIProgressUpdate = IProgressUpdate;
        }
        
        public void removeProgressUpdate(){
            mIProgressUpdate = null;
        }
    
        private void initClient(){
            if(mClient==null) {
                File file = new File(CACHE_PATH);
                if(!file.exists()){
                    file.mkdirs();
                }
                OkHttpClient.Builder builder = new OkHttpClient.Builder()
                        .connectTimeout(TIME_OUT,TimeUnit.SECONDS)
                        .cache(new Cache(file,20 * 1024 * 1024));
                builder.addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Response response = chain.proceed(chain.request());
                        return response.newBuilder()
                                .body(new ProcessResponseBody(response.body(), new ProcessResponseBody.ProgressListener() {
                                    @Override
                                    public void update(int progress) {
                                        if(mIProgressUpdate!=null){
                                            mIProgressUpdate.update(progress);
                                        }
                                    }
                                }))
                                .build();
                    }
                });
                mClient = builder.build();
            }
        }
    
        public Disposable requestGet(String url, ICallBack callBack){
            return request(url,null,callBack);
        }
    
        public <T>Disposable requestPost(String url,T data,ICallBack callBack){
            return request(url,mGson.toJson(data),callBack);
        }
    
        public <T>Disposable requestPost(String url, List<T> data,ICallBack callBack){
            return request(url,mGson.toJson(data),callBack);
        }
    
        public Disposable request(String url, String postData, ICallBack callBack) {
            Request.Builder builder = new Request.Builder().url(url);
            if (postData != null) {
                RequestBody body = RequestBody.create(MediaType.parse("application/json ; charset=utf-8"), postData);
                builder.post(body);
            }
            Request request = builder.build();
            Flowable flowable = Flowable.create(new FlowableOnSubscribe<String>() {
                @Override
                public void subscribe(FlowableEmitter<String> emitter) throws Exception {
                    mClient.newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            LogUtils.LogE("接口失败", e.getLocalizedMessage());
                            emitter.onError(e);
                        }
    
                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            switch (response.code()) {
                                case 200:
                                    String result = response.body().string();
                                    LogUtils.LogI("接口成功", result);
                                    if (TextUtils.isEmpty(result)) {
                                        emitter.onError(new Throwable("未获取到数据"));
                                    } else {
                                        emitter.onNext(result);
                                    }
                                    break;
                                case 500:
                                    LogUtils.LogI("接口失败", "服务器错误");
                                    emitter.onError(new Throwable("服务器错误"));
                                    break;
                                case 403:
                                    LogUtils.LogI("接口失败", "服务器拒绝请求");
                                    emitter.onError(new Throwable("服务器拒绝请求"));
                                    break;
                                default:
                                    LogUtils.LogI("接口失败", "请求失败");
                                    emitter.onError(new Throwable("请求失败"));
                                    break;
                            }
                            emitter.onComplete();
                        }
                    });
                }
            }, BackpressureStrategy.ERROR).map(new Function<String, HttpData>() {
                @Override
                public HttpData apply(String s) throws Exception {
                    return mGson.fromJson(s, HttpData.class);
                }
            }).observeOn(AndroidSchedulers.mainThread());
            Disposable disposable = flowable.subscribe(new Consumer<HttpData>() {
                @Override
                public void accept(HttpData httpData) throws Exception {
                    switch (httpData.getRetCode()) {
                        case HttpData.SUCCESS_CODE:
                            callBack.success(httpData.getRetObject());
                            break;
                        default:
                            callBack.failure(httpData.getRetMessage());
                            break;
                    }
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    callBack.finish();
                    callBack.failure(throwable.getMessage());
                }
            }, new Action() {
                @Override
                public void run() throws Exception {
                    callBack.finish();
                }
            });
            return disposable;
        }
    
        public void cancelAll(){
            mClient.dispatcher().cancelAll();
        }
    
        public interface ICallBack{
            void finish();
            void failure(String errorMsg);
            void success(String dara);
        }
    
        public static abstract class absCallBack implements ICallBack{
            @Override
            public void finish() {}
        }
        
        public interface IProgressUpdate{
            void update(int progress);
        }
    }
    

    ProcessResponseBody继承自ResPonseBody,可以监听进度:

    public class ProcessResponseBody extends ResponseBody {
        private ResponseBody mResponseBody;
        private ProgressListener mProgressListener;
        private BufferedSource mBufferedSource;
    
        public ProcessResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
            mResponseBody = responseBody;
            mProgressListener = progressListener;
        }
    
        @Override
        public MediaType contentType() {
            return MediaType.parse("application/json ; charset=utf-8");
        }
    
        @Override
        public long contentLength() {
            return 0;
        }
    
        @Override
        public BufferedSource source() {
            if(mBufferedSource==null){
                mBufferedSource = Okio.buffer(getSource(mResponseBody.source()));
            }
            return mBufferedSource;
        }
    
        private Source getSource(Source source){
            return new ForwardingSource(source) {
                long totalBytesRead = 0L;
                @Override
                public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead = super.read(sink, byteCount);
                    totalBytesRead += bytesRead != -1 ? bytesRead : 0;
                    if(mProgressListener!=null){
                        mProgressListener.update((int)((100*totalBytesRead)/mResponseBody.contentLength()));
                    }
                    return bytesRead;
                }
            };
        }
    
        public interface ProgressListener{
            void update(int progress);
        }
    }
    

    相关文章

      网友评论

          本文标题:OKHTTP

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