okHttp3学习总结

OkHttp3

okHttp3 是一个 Android的基于Http的网络开源框架,是由 square 公司开发。

现在网上比较推荐的两个 Android 网络开源框架,一个是 okHttp,另一个是 Retrofit
,而 Retrofit 是根据 okHttp封装的框架。所以关于Android网络部分,okHttp是必须要学习的一个知识。

[官网地址] (https://github.com/square/okhttp)

项目中引用 okHttp3 只需要在 app 的 build.gradle 中引用 compile ‘com.squareup.okhttp3:okhttp:3.6.0’ 即可。

[慕课网洪洋大神的okHttp视频]
(http://www.imooc.com/learn/764)
[参考的简书文章]
(http://www.jianshu.com/p/964bb1b2d345)
[参考的CSDN文章]
(http://blog.csdn.net/itachi85/article/details/51190687)

1.okHttp3的基本用法
首先,不管是 Get 请求还是 Post 请求,同步或者异步,okHttp3的请求总体分为三步:

  1. 构造出一个okHttp3下的Request对象
  2. 通过这个Request对象,构造出一个Call对象
  3. 调用这个call对象的同步或者异步方法执行网络访问

示例如下:

    //构造出一个Request对象,address是访问的服务器地址,当前示例是get方式访问
    Request request = new Request.Builder().url(address).get().build();
    //通过上面的request对象,构造出一个Call对象,sOkHttpClient为全局的OkHttpClient对象
    Call call = sOkHttpClient.newCall(request);
    //call执行enqueue(异步)或者execute(同步),callback为异步执行时的回调对象
    call.enqueue(callback);

2.okHttp3下的Get请求方式

 /**
 * Get请求方法
 * @param view
 */
public void doGet(View view){
    String address = baseUrl + "login?username=hblolj&password=123456";
    HttpUtils.sendOkHttpRequestByGet(address, new Callback() {
        //请求失败的回调
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }
        //请求成功的回调
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //拿到服务器返回的数据
            final String result = response.body().string();
            Log.i(TAG, "onResponse: " + result);
            //因为是enqueue异步执行,所以只有在主线程中才可以更新UI
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_result.setText(result);
                }
            });
        }
    });
}

/**
 * HttpUtils中的Get请求方法
 * @param address  get方式的请求地址
 * @param callback 回调对象
 */
public static void sendOkHttpRequestByGet(String address , Callback callback){
    Request request = new Request.Builder().url(address).get().build();
    Call call = sOkHttpClient.newCall(request);
    call.enqueue(callback);
}

3.okHttp3下的Post请求方式(键值对型)

Tips:post请求默认的类型是:application/x-www-form-urlencoded

  //在OkHttp3的源码中FormBody 的源码    
  private static final MediaType CONTENT_TYPE =
  MediaType.parse("application/x-www-form-urlencoded");

根据 MediaType 的类型,post选择对上传的数据是否进行编码处理。如果为 multipart/form-data 类型表示上传的是文件,则不用进行编码处理。

/**
 * Post请求方法
 * @param view
 */
public void doPost(View view){
    //登录接口
    String address = baseUrl + "login";
    Map<String, String> map = new HashMap<>();
    map.put("username", "hblolj");
    map.put("password", "123456");
    HttpUtils.sendOkHttpRequestByPost(address, new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String result = response.body().string();
            Log.i(TAG, "onResponse: " + result);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_result.setText(result);
                }
            });
        }
    }, map);
}

/**
 * HttpUtils中的post请求方法
 * @param address  post请求的地址
 * @param callback 回调对象
 * @param maps     post请求的参数
 */
public static void sendOkHttpRequestByPost(String address, Callback callback, Map<String, String> maps){
    //根据参数中的maps拼装出RequestBody,用来保存参数,默认的MediaType
    RequestBody requestBody = new FormBody.Builder()
            .add("username", maps.get("username"))
            .add("password", maps.get("password"))
            .build();
    //将请求地址与请求参数设置给Request
    Request request = new Request.Builder().url(address).post(requestBody).build();
    //构造Call对象
    Call call = sOkHttpClient.newCall(request);
    //异步执行网络访问
    call.enqueue(callback);
}

4.okHttp3下的Post请求方式(String型)

/**
 * Post请求上传字符串
 * @param view
 */
public void doPostString(View view){
    String address = baseUrl + "postString";
    HttpUtils.sendOkHttpRequestByPostString(address, new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String result = response.body().string();
            Log.i(TAG, "onResponse: " + result);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_result.setText(result);
                }
            });
        }
    }, "我是通过PostString传递的字符内容");
}

/**
 * Post上传字符串方法
 * @param address  服务器地址
 * @param callback 回调对象
 * @param value    上传的字符串
 */
public static void sendOkHttpRequestByPostString(String address, Callback callback, String value){
    //相对于键值对类型,这里指定了MediaType
    RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), value);
    //构造Request
    Request request = new Request.Builder().url(address).post(requestBody).build();
    //构造Call
    Call call = sOkHttpClient.newCall(request);
    //异步执行
    call.enqueue(callback);
}

5.okHttp3下的Post请求方式(File型)

/**
 * Post请求上传文件
 * @param view
 */
public void doPostFile(View view){
    String address = baseUrl + "postFile";
    //从内存卡获取文件
    File file = new File(Environment.getExternalStorageDirectory(), "shareimg.png");
    if (!file.exists()){
        Log.i(TAG, "文件不存在");
        tv_result.setText("文件不存在!");
        return;
    }
    HttpUtils.sendOkHttpRequestByPostFile(address, new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String result = response.body().string();
            Log.i(TAG, "onResponse: " + result);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_result.setText(result);
                }
            });
        }
    }, file);
}

/**
 * Post方法上传文件
 * @param address   完整的请求地址
 * @param callback  回调对象
 * @param file      上传的文件对象
 */
public static void sendOkHttpRequestByPostFile(String address, Callback callback, File file){
    //指定了MediaType为application/octet-stream,并且传入File生成requestBody
    RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
    //构造Request
    Request request = new Request.Builder().url(address).post(requestBody).build();
    //构造Call
    Call call = sOkHttpClient.newCall(request);
    //异步执行
    call.enqueue(callback);
}

6.okHttp3下的文件上传

/**
 * okHttp3下的文件上传
 * @param view
 */
public void doUpload(View view){
    String address = baseUrl + "uploadFile";
    File file = new File(Environment.getExternalStorageDirectory(), "tagPicture.jpg");
    if (!file.exists()){
        Log.i(TAG, "文件不存在");
        tv_result.setText("文件不存在!");
        return;
    }
    HttpUtils.sendOkHttpRequestByUpload(address, new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String result = response.body().string();
            Log.i(TAG, "onResponse: " + result);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_result.setText(result);
                }
            });
        }
    }, file);
}

/**
 * okHttp3下的文件时上传
 * @param address  访问的地址
 * @param callback 回调对象
 * @param file     上传的文件
 */
public static void sendOkHttpRequestByUpload(String address, Callback callback, File file){
    //构造MultipartBody(复合Body)
    MultipartBody multipartBody = new MultipartBody.Builder()
            //配置上传的类型
            .setType(MultipartBody.FORM)
            //上传的普通键值对
            .addFormDataPart("username", "hblolj")
            .addFormDataPart("password", "123456")
            //参数对应为name, fileName, reuqestBody
            .addFormDataPart("picture", "一张照片.jpg",
                //构造文件类型RequestBody
                RequestBody.create(MediaType.parse("application/octet-stream"), file))
            .build();
    //构造Request
    Request request = new Request.Builder().url(address).post(multipartBody).build();
    //构造Call
    Call call = sOkHttpClient.newCall(request);
    //异步执行
    call.enqueue(callback);
}

7.okHttp3下的文件下载

/**
 * okhttp3下的文件下载
 * @param view
 */
public void doDownloadFile(View view){
    //下载地址
    String address = baseUrl + "files/picture.jpg";
    HttpUtils.sendOkHttpRequestByDownloadFile(address, new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //拿到服务器下载文件的输入流
            InputStream is = response.body().byteStream();
            //本地新建文件
            File file = new File(Environment.getExternalStorageDirectory(), "一张照片6666.jpg");
            //拿到新建文件的输出流
            FileOutputStream fout = new FileOutputStream(file);
            //模板代码,将下载文件的输入流写到新建文件
            int len = 0;
            byte[] buf = new byte[128];
            while((len = is.read(buf)) != -1){
                fout.write(buf, 0, len);
            }
            fout.flush();
            fout.close();
            is.close();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_result.setText("下载成功");
                }
            });
        }
    });
}

/**
 * okhttp3下的文件下载
 * 找到下载地址,就是普通的Get访问
 * @param address  下载地址
 * @param callback 回调对象
 */
public static void sendOkHttpRequestByDownloadFile(String address, Callback callback){
    Request request = new Request.Builder().url(address).get().build();

    Call call = sOkHttpClient.newCall(request);
    call.enqueue(callback);
}

8.okHttp3下的Session保持与缓存

/**
 * 全局的okHttpClient
 */
private static OkHttpClient sOkHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJar() {

        private Map<String, List<Cookie>> cookieStore = new HashMap<String, List<Cookie>>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            //根据请求的host保存cookies到内存,达到session的保存
            Log.d("HttpUtils", "host: " + url.host());
            cookieStore.put(url.host(), cookies);
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            List<Cookie> cookies = cookieStore.get(url.host());
            return cookies!=null?cookies : new ArrayList<Cookie>();
        }
    })
        //设置连接超时时间
        .connectTimeout(1500, TimeUnit.MILLISECONDS)
        .readTimeout(2000, TimeUnit.MILLISECONDS)
        .writeTimeout(2000, TimeUnit.MILLISECONDS)
        //设置保存缓存的文件以及大小限制
        .cache(new Cache(file , 10*1024*1024))
        .build();   

9.okHttp3的框架封装

参考开始的推荐文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值