Android网络请求OKHttp详解
在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; }
下一篇: c/c++ 继承与多态 容器与继承3