android http——OkHttp使用详解

来源:互联网 发布:linux 安装rpm 编辑:程序博客网 时间:2024/04/16 05:40

okhttp已经被google认定为推荐的android请求框架,我们也可以在as中直接加入:
这里写图片描述

okhttp的依赖库是:

compile 'com.squareup.okhttp:okhttp:2.5'

当然,作为eclipse的开发者来说,就不能使用依赖库了。

有位同行在博客中写了okhttp的官方文档,可以看看。

我着重介绍okhttp的使用方法。

我们将okhttp所有的网络请求方式都写在RequestHandle类中。

需要注意的几点是,
1,RequestHandle使用单例。因为okhttp使用单例来操作实例。
2,线程阻塞方式的请求需要在非ui线程中。
3,异步回调结果还处在非ui线程中,所以如果要更新ui,需要handler。

1,将RequestHandle写成单例模式:

/**     * 单例请求网络,只能传入baseactivity     */    private static volatile RequestHandle requestHandle = null;    public synchronized static RequestHandle getRequestInterface() {        if (requestHandle == null) {            synchronized (RequestHandle.class) {                if (requestHandle == null) {                    requestHandle = new RequestHandle();                }            }        }        return requestHandle;    }

2,定义常量和初始化对象

    //创建队列,用于异步调用    private Request request;    //线程阻塞方式调用    private Response response;    //访问对象    private Call call;    //okhttp实例    private OkHttpClient mOkHttpClient;    //线程阻塞方式请求的get,post状态码    private final static int GET_INSTANCE = 0;    private final static int POST_INSTANCE = 1;    //默认超时时间    private final static int VALUE_DEFAULT_TIME_OUT = 20 * 1000;    /**     * 参数类型     * "text", 文本     * "image", 图片     * "audio",音频     * "video",视频     * "object",其他     */    private static final MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/x-markdown; charset=utf-8");    private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("image/png");    private static final MediaType MEDIA_TYPE_AUDIO = MediaType.parse("audio/mp3");    private static final MediaType MEDIA_TYPE_VIDEO = MediaType.parse("video/mp4");    private static final MediaType MEDIA_TYPE_OBJECT = MediaType.parse("application/octet-stream");    private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");//给每个网络请求的标记    public static final String TAG_DATA = "tag_data";    public static final String TAG_IMAGE = "tag_image";    public static final String TAG_FILE = "tag_file";private RequestHandle() {        //创建okHttpClient对象        mOkHttpClient = new OkHttpClient();        mOkHttpClient.setConnectTimeout(VALUE_DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS);//连接超时        mOkHttpClient.setReadTimeout(VALUE_DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS);//读取超时        mOkHttpClient.setWriteTimeout(VALUE_DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS);//写入超时    }

3,线程阻塞的请求,即非异步的。
get请求

/**     * 线程阻塞的单例发送get请求,线程阻塞的方式需要在非ui线程中     */    public void sendGetRequestBlocking(String url) {        try {            //创建一个请求            request = new Request                    .Builder()                    .tag(TAG_DATA)                    .url(url)                    .build();            response = mOkHttpClient.newCall(request).execute();            callBackByEnqueueBlocking(response);        } catch (IOException e) {            e.printStackTrace();            return;        }    }

post请求:

/**     * 异步的post请求,线程阻塞的方式需要在非ui线程中     *     * @param url     请求地址     * @param builder 请求参数     */    public void sendPostRequestBlocking(String url, MultipartBuilder builder) {        sendPostRequestBlocking(url, builder, null);    }

post上传文件:

/**异步的post请求,线程阻塞的方式需要在非ui线程中,可以附带文件     * @param url     * @param builder     * @param files     */    public void sendPostRequestBlocking(String url, MultipartBuilder builder, File[] files) {        try {            //builder.addFormDataPart("参数", "值");            if (files != null && files.length != 0) {                //遍历file数组,得到所有file文件                for (File file : files) {                    builder.addFormDataPart("file", file.getName(), RequestBody.create(MEDIA_TYPE_OBJECT, file));                }            }            String tag = files == null ? TAG_DATA : TAG_FILE;            request = new Request.Builder()                    .url(url)                    .tag(tag)                    .post(builder.build())                    .build();            response = mOkHttpClient.newCall(request).execute();            callBackByEnqueueBlocking(response);        } catch (IOException e) {            e.printStackTrace();        }    }

线程阻塞请求的结果处理:

//队列请求(线程阻塞)的结果处理方法    public void callBackByEnqueueBlocking(Response response) {        try {            //判断是否是成功的            if (response.isSuccessful()) {                //成功                //String jsonStr=response.body().string();//字符串,无编码                String jsonStr = new String(response.body().bytes(), "UTF-8");//二进制字节数组                //InputStream inputStream=response.body().byteStream();//输入流                try {                    JSONObject jsonObject = new JSONObject(jsonStr);                    //解析数据处理                    //发送数据处理                } catch (JSONException e) {                    e.printStackTrace();                }            } else {                //失败                response.code();//失败码                response.message();//失败信息            }        } catch (IOException e) {            e.printStackTrace();        }    }

4,异步请求

get请求

/**     * 异步get请求     *     * @param url 请求的哪个接口,异步请求     */    public void sendGetRequest(String url) {        //创建一个Request        request = new Request.Builder()                .url(url)                .tag(TAG_DATA)                .build();        call = mOkHttpClient.newCall(request);        callBackByEnqueue(call);    }

post请求

 /**     * 异步的post请求     */    public void sendPostRequest(String url, MultipartBuilder builder) {        sendPostRequest(url, builder, null);    }

post上传文件

/** 异步的post请求,传文件     * @param url     * @param builder     * @param files     */    public void sendPostRequest(String url, MultipartBuilder builder, File[] files) {        //builder.addFormDataPart("参数", "值");        if (files != null && files.length != 0) {            //遍历file数组,得到所有file文件            for (File file : files) {                builder.addFormDataPart("file", file.getName(), RequestBody.create(MEDIA_TYPE_OBJECT, file));            }        }        String tag = files == null ? TAG_DATA : TAG_FILE;        request = new Request.Builder()                .url(url)                .tag(tag)                .post(builder.build())                .build();        call = mOkHttpClient.newCall(request);        callBackByEnqueue(call);    }

异步请求结果回调处理:

//队列请求(异步)的结果处理方法    public void callBackByEnqueue(Call call) {        //new call        call = mOkHttpClient.newCall(request);        //需要注意的是异步回调还是在子线程中,所以如果要更新ui,则记得handler        call.enqueue(new Callback() {            @Override            public void onFailure(Request request, IOException e) {                //失败            }            @Override            public void onResponse(Response response) {                //响应                try {                    if (response.isSuccessful()) {                        //String jsonStr=response.body().string();//字符串,无编码                        String jsonStr = null;//二进制字节数组                        jsonStr = new String(response.body().bytes(), "UTF-8");                        //InputStream inputStream=response.body().byteStream();//输入流                        try {                            JSONObject jsonObject = new JSONObject(jsonStr);                            //解析数据处理                            //发送数据处理                        } catch (JSONException e) {                            e.printStackTrace();                        }                    } else {                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        });    }

5,设置超时

/**     * 设置超时     *     * @param value     */    public void setTimeOut(int value) {        if (mOkHttpClient == null) return;        mOkHttpClient.setConnectTimeout(value, TimeUnit.MILLISECONDS);//连接超时        mOkHttpClient.setReadTimeout(value, TimeUnit.MILLISECONDS);//读取超时        mOkHttpClient.setWriteTimeout(value, TimeUnit.MILLISECONDS);//写入超时    }

6,清除一个正在请求的操作

/**     * 取消一个当前正在处理的Call     * 使用Call.cancel()可以立即停止掉一个正在执行的call。     * 注意:如果一个线程正在写请求或者读响应,将会引发IOException。     */    public void cancelByCall() {        if (call != null) {            try {                call.cancel();            } catch (Exception e) {                e.printStackTrace();            }        }    }

7,清除所有的请求

/**     * 清楚所有网络请求     * 你可以通过tags来同时取消多个请求。     * 当你构建一请求时,使用RequestBuilder.tag(tag)来分配一个标签。     * 之后你就可以用OkHttpClient.cancel(tag)来取消所有带有这个tag的call。     *     * @param isCancelAllRequests     */    public void cancelAllRequests(boolean isCancelAllRequests) {        if (mOkHttpClient != null) {            try {                if (isCancelAllRequests) {                    mOkHttpClient.cancel(TAG_DATA);                    mOkHttpClient.cancel(TAG_IMAGE);                    mOkHttpClient.cancel(TAG_FILE);                }            } catch (Exception e) {                e.printStackTrace();            }        }    }

8,文件下载、上传带进度显示
因为okhttp自身无法显示下载进度,所以借用网上的代码实现下载进度显示。

下载进度回调

/**     * 非ui线程回调文件下载进度     * 这个是非ui线程回调,不可直接操作UI     */    final ProgressListener progressResponseListener = new ProgressListener() {        @Override        public void onProgress(long bytesRead, long contentLength, boolean done) {            //长度未知的情况下回返回-1            if (contentLength != -1 && (100 * bytesRead) / contentLength >= 0) {                String donePercent = (100 * bytesRead) / contentLength + "%";//上传进度            }        }    };

下载方法:

/**     * 下载文件     *     * @param url     */    public void downloadFile(String url) {        request = new Request.Builder()                .url(url)                .build();        //包装Response使其支持进度回调        ProgressHelper.addProgressResponseListener(mOkHttpClient, progressResponseListener)                .newCall(request)                .enqueue(new Callback() {                    @Override                    public void onFailure(Request request, IOException e) {                        String message;                        if (!NetWorkUtil.isNetworkConnected(UIAppliaction.getInstance())) {                            //判断是否是因为没有网络的原因                            message = "网络不给给力";                        } else {                            message = e.getMessage();                        }                    }                    @Override                    public void onResponse(Response response) throws IOException {                        String message = "";                        String url = response.request().url().getPath();                        //获得url地址的文件后缀名                        String filename = url.substring(message.indexOf("."), message.length());                        InputStream inputStream = response.body().byteStream();//输入流                        //通过流保存文件的工具类                        if (FileUtil.insertSDCardFromInput("文件绝对路径", filename, inputStream))                            message = "下载完成";                        else                            message = "文件保存失败";                    }                });    }

至于其中回调的方法我这里就只贴出代码。因为是别人处理的代码,我就分享下载地址。
http://pan.baidu.com/s/1i4GIJtz
ec32
代码经测试回调进度是正常的。

这些就是基本的okhttp的使用。自己经过封装后用起来也是非常方便的。这里分享出来供大家学习。

2 0
原创粉丝点击