当前位置: 移动技术网 > 移动技术>移动开发>Android > Android网络请求OKHttp详解

Android网络请求OKHttp详解

2019年01月05日  | 移动技术网移动技术  | 我要评论

android studio中引入包

compile ‘com.squareup.okhttp3:okhttp:3.4.1’

具体使用?
okhttp提供异步请求跟同步请求,android中主要用到异步请求

一、get的异步请求

public void get() {
    okhttpclient client = new okhttpclient();
    request request = new request.builder()
            .url("https://www.baidu.com")
            .build();
    client.newcall(request).enqueue(new callback() {
        @override
        public void onfailure(call call, ioexception e) {
           logutils.w("获取数据失败了");
        }

        @override
        public void onresponse(call call, response response) throws ioexception {
            logutils.w("获取数据成功了");
            logutils.w("response.code()==" + response.code());
            logutils.w("response.body().string()==" + response.body().string());
        }
    });
}

返回结果

获取数据成功了
response.code()==200
response.body().string()=={....}

注意?
- 回调接口的onfailure方法和onresponse执行在子线程?
- response.code是http响应行中的code,如果访问成功则返回200.这个不是服务器设置的,而是http协议中状态码?
- response.body().string()本质是输入流的读操作,所以它还是网络请求的一部分,所以这行代码必须放在子线程?
- response.body().string()只能调用一次,在第一次时有返回值,第二次再调用时将会返回null。因为response.body().string()的本质是输入流的读操作,必须有服务器的输出流的写操作时客户端的读操作才能得到数据。而服务器的写操作只执行一次,所以客户端的读操作也只能执行一次,第二次将返回null

二、post异步请求

public void post() {
    okhttpclient client = new okhttpclient();//创建okhttpclient对象。
    formbody.builder formbody = new formbody.builder();//创建表单请求体
    formbody.add("username", "zhangsan");//传递键值对参数
    request request = new request.builder()//创建request 对象。
            .url("https://www.baidu.com")
            .post(formbody.build())//传递请求体
            .build();
    client.newcall(request).enqueue(new callback() {
        @override
        public void onfailure(call call, ioexception e) {
            //回调方法的使用与get异步请求相同
        }

        @override
        public void onresponse(call call, response response) throws ioexception {
            //回调方法的使用与get异步请求相同
        }
    });
}
okhttp中没有设置get/post请求方式,默认是get请求,当调用post(formbody.build())时自动修改请求方式为post

三、post请求参数传递方式

使用request.builder类中的post(requestbody body)方法传递

post方法接收的参数是requestbody 对象,所以只要是requestbody 类以及子类对象都可以当作参数进行传递。formbody就是requestbody 的一个子类对象

使用formbody传递键值对参数

public void postdatawithparame() {
    okhttpclient client = new okhttpclient();//创建okhttpclient对象。
    formbody.builder formbody = new formbody.builder();//创建表单请求体
    formbody.add("username","zhangsan");//传递键值对参数
    request request = new request.builder()//创建request 对象。
            .url("https://www.baidu.com")
            .post(formbody.build())//传递请求体
            .build();
    client.newcall(request).enqueue(new callback() {。。。});//此处省略回调方法。
}

使用requestbody传递json或file对象

requestbody是抽象类,故不能直接使用,但是他有静态方法create,使用这个方法可以得到requestbody对象

这种方式可以上传json对象或file对象?
上传json对象使用示例如下

okhttpclient client = new okhttpclient();//创建okhttpclient对象。
mediatype json = mediatype.parse("application/json; charset=utf-8");//数据类型为json格式,
string jsonstr = "{\"username\":\"lisi\",\"nickname\":\"李四\"}";//json数据.
requestbody body = requestbody.create(json, josnstr);
request request = new request.builder()
        .url("https://www.baidu.com")
        .post(body)
        .build();
client.newcall(request).enqueue(new callback() {。。。});//此处省略回调方法。

上传file对象使用示例如下

okhttpclient client = new okhttpclient();//创建okhttpclient对象。
mediatype filetype = mediatype.parse("file/*");//数据类型为json格式,
file file = new file("path");//file对象.
requestbody body = requestbody.create(filetype , file );
request request = new request.builder()
        .url("https://www.baidu.com")
        .post(body)
        .build();
client.newcall(request).enqueue(new callback() {。。。});//此处省略回调方法。

使用multipartbody同时传递键值对参数和file对象

okhttpclient client = new okhttpclient();
multipartbody multipartbody =new multipartbody.builder()
        .settype(multipartbody.form)
        .addformdatapart("groupid",""+groupid)//添加键值对参数
        .addformdatapart("title","title")
        .addformdatapart("file",file.getname(),requestbody.create(mediatype.parse("file/*"), file))//添加文件
        .build();
final request request = new request.builder()
        .url(urlcontant.chat_room_subject_image)
        .post(multipartbody)
        .build();
client.newcall(request).enqueue(new callback() {。。。});

自定义requestbody实现流的上传

requestbody body = new requestbody() {
    @override
    public mediatype contenttype() {
        return null;
    }

    @override
    public void writeto(bufferedsink sink) throws ioexception {//重写writeto方法
        fileinputstream fio= new fileinputstream(new file("filename"));
        byte[] buffer = new byte[1024*8];
        if(fio.read(buffer) != -1){
             sink.write(buffer);
        }
    }
};

四、设置请求头

request request = new request.builder()
                .url("https://www.baidu.com")
                .header("user-agent", "okhttp headers.java")
                .addheader("token", "mytoken")
                .build();

五、下载文件

在okhttp中并没有提供下载文件的功能,但是在response中可以获取流对象,有了流对象我们就可以自己实现文件的下载,在回调接口callback的onresponse方法中调用

try{
    inputstream  is = response.body().bytestream();//从服务器得到输入流对象
    long sum = 0;
    file dir = new file(mdestfiledir);
    if (!dir.exists()){
        dir.mkdirs();
    }
    file file = new file(dir, mdestfilename);//根据目录和文件名得到file对象
    fileoutputstream  fos = new fileoutputstream(file);
    byte[] buf = new byte[1024*8];
    int len = 0;
    while ((len = is.read(buf)) != -1){
        fos.write(buf, 0, len);
    }
    fos.flush();
    return file;
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网