Android-Okhttp的使用解析
okhttp是android6.0推出的网络框架。由于谷歌在android6.0的之后,将httpclient相关属性取消掉,导致volley框架不能正常使用。所以才有了今天的okhttp。
okhttp进行网络访问通常有两种方式,一种是get请求,还有一种叫做post请求。
1、okhttp的get请求
通常,我们使用get方式来请求一个网站,是依靠url地址的。okhttp使用get方式来请求网站通常有如下的步骤:
a、创建okhttpclient的变量,这个变量相当于是一个全局的执行者。主要的网络操作是依靠它来进行的。
b、创建一个builder对象。
c、利用builder对象创建一个request对象。
d、使用全局执行者来创建一个call对象。
e、通过call对象来进行网络连接。
public void doget(view view) { request.builder builder = new request.builder(); request request = builder.get().url(urlstring + "username=pby&userpassword=123").build(); call newcall = mokhttpclient.newcall(request); //newcall.execute() newcall.enqueue(new callback() { @override public void onfailure(request request, ioexception e) { l.e("失败了"); } @override public void onresponse(response response) throws ioexception { string string = response.body().string(); l.e(string); } }); }
2、okhttp的post请求
post请求与get请求有些不一样。get请求主要的功能是从服务器上获取数据,而post请求则是向服务器提交数据。
public void dopost(view view) { formencodingbuilder requestbodybuilder = new formencodingbuilder(); requestbody requestbody = requestbodybuilder.add("username", "pby").add("userpassword", "123").build(); request.builder builder = new request.builder(); request request = builder.url(urlstring).post(requestbody).build(); call newcall = mokhttpclient.newcall(request); executecall(newcall); }
3、服务器端接收客户端传过来的字符串
客户端的代码:
public void dopoststring(view view) { requestbody requestbody = requestbody.create(mediatype.parse("text/plain;charset = utf-8"), "{name = pby, password = 1234}"); request.builder builder = new request.builder(); request request = builder.url(urlstring + "dopoststring").post(requestbody).build(); call newcall = mokhttpclient.newcall(request); executecall(newcall); }
服务器端的代码:
public string dopoststring() throws ioexception { httpservletrequest request = servletactioncontext.getrequest(); servletinputstream inputstream = request.getinputstream(); stringbuilder sb = new stringbuilder(); int len = 0; byte []buff = new byte[1024]; while((len = inputstream.read(buff)) != -1) { sb.append(new string(buff, 0, len)); } system.out.println(sb.tostring()); return null; }
服务器端如果要接收客户端的数据,则需要接收request;如果服务器端想要给客户端传数据,则需要通过response来传递。
4、使用post方式进行文件的传输
客户端的代码
public void dopost(view view) { formencodingbuilder requestbodybuilder = new formencodingbuilder(); requestbody requestbody = requestbodybuilder.add("username", "pby").add("userpassword", "123").build(); request.builder builder = new request.builder(); request request = builder.url(urlstring + "login").post(requestbody).build(); call newcall = mokhttpclient.newcall(request); executecall(newcall); }
关于选择文件的代码--抄袭网络上的代码,并不是自己写的
private void showfilechooser() { intent intent = new intent(intent.action_get_content); intent.settype("*/*"); intent.addcategory(intent.category_openable); try { startactivityforresult( intent.createchooser(intent, "select a file to upload"), 1); } catch (android.content.activitynotfoundexception ex) { toast.maketext(this, "please install a file manager.", toast.length_short).show(); } } @override protected void onactivityresult(int requestcode, int resultcode, intent data) { switch (requestcode) { case 1: if (resultcode == result_ok) { // get the uri of the selected file uri uri = data.getdata(); string path = fileutils.getpath(this, uri); if(path != null) { postfile(path); } } break; } super.onactivityresult(requestcode, resultcode, data); }
在进行这个的操作的时候,一定要记住增加读和写的权限,否则会上传失败的。
服务器端的代码
public string dopostfile() throws ioexception { httpservletrequest request = servletactioncontext.getrequest(); servletinputstream inputstream = request.getinputstream(); string dir = servletactioncontext.getservletcontext().getrealpath("files"); file file = new file(dir, "abc.jpg"); fileoutputstream fos = new fileoutputstream(file); int len = 0; byte [] buff = new byte[1024]; while((len = inputstream.read(buff)) != -1) { fos.write(buff, 0, len); } fos.flush(); fos.close(); return null; }
上面显示的files文件,在tomcat的webapps下的工程名名文件下的fies文件夹(才开始是没有这个文件夹的,需要手动自己创建)。
5.使用post方式来上传文件
客户端代码:
private void uploadfile(string path) { file file = new file(path); if(!file.exists()) { return ; } multipartbuilder multipartbuilder = new multipartbuilder(); requestbody requestbody = multipartbuilder.type(multipartbuilder.form) .addformdatapart("username", "pby") .addformdatapart("userpassword", "123") .addformdatapart("mfile", file.getname(), requestbody.create(mediatype.parse("application/octet-stream"), file)).build(); // countingrequestbody countingrequestbody = new countingrequestbody(requestbody, new countingrequestbody.mylistener() { // @override // public void onrequestprogress(int bytewritecount, int totalcount) { // l.e(bytewritecount + " / " + totalcount); // } // }); request.builder builder = new request.builder(); //request request = builder.url(urlstring + "douploadfile").post(countingrequestbody).build(); request request = builder.url(urlstring + "douploadfile").post(requestbody).build(); call newcall = mokhttpclient.newcall(request); executecall(newcall); }
服务器端的代码:
public string douploadfile() { if(mfile == null) { system.out.println(mfilefilename+" is null.."); return null; } string dir = servletactioncontext.getservletcontext().getrealpath("files"); file file = new file(dir, mfilefilename); try { fileutils.copyfile(mfile, file); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } return null; }
在上传文件的时候,有一个小细节都注意到:就是tomcat服务器只允许上传2m以下的文件。要想上传大文件,就必须在struct文件中加一句:<constant name="struts.multipart.maxsize" value="1024000000"/>数字表示自定义大小的限制。
6.上传文件时,进度的显示问题
在写代码的时候我们知道,我们不能直接获得上传文件的进度。因为这些数据都是封装在requestbody里面的,要想使用只有通过回调接口来实现。
package com.example.android_okhttp; import com.squareup.okhttp.mediatype; import com.squareup.okhttp.requestbody; import java.io.ioexception; import okio.buffer; import okio.bufferedsink; import okio.forwardingsink; import okio.okio; import okio.sink; /** * created by 前世诀别的一纸书 on 2017/3/5. */ public class countingrequestbody extends requestbody { private requestbody delegate = null; private mylistener mlistener= null; private countingsink mcountsink = null; public interface mylistener { void onrequestprogress(int bytewritecount, int totalcount); } public countingrequestbody(requestbody requestbody, mylistener listener) { delegate = requestbody; mlistener = listener; } @override public mediatype contenttype() { return delegate.contenttype(); } @override public void writeto(bufferedsink sink) throws ioexception { mcountsink = new countingsink(sink); bufferedsink bs = okio.buffer(mcountsink); delegate.writeto(bs); bs.flush(); } private class countingsink extends forwardingsink{ private int bytewritecount = 0; public countingsink(sink delegate) { super(delegate); } @override public void write(buffer source, long bytecount) throws ioexception { super.write(source, bytecount); bytewritecount += bytecount; mlistener.onrequestprogress(bytewritecount, (int) contentlength()); } } @override public long contentlength() throws ioexception { return delegate.contentlength(); } }
multipartbuilder multipartbuilder = new multipartbuilder(); requestbody requestbody = multipartbuilder.type(multipartbuilder.form) .addformdatapart("username", "pby") .addformdatapart("userpassword", "123") .addformdatapart("mfile", file.getname(), requestbody.create(mediatype.parse("application/octet-stream"), file)).build(); countingrequestbody countingrequestbody = new countingrequestbody(requestbody, new countingrequestbody.mylistener() { @override public void onrequestprogress(int bytewritecount, int totalcount) { l.e(bytewritecount + " / " + totalcount); } }); request.builder builder = new request.builder(); request request = builder.url(urlstring + "douploadfile").post(countingrequestbody).build(); //request request = builder.url(urlstring + "douploadfile").post(requestbody).build(); call newcall = mokhttpclient.newcall(request);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Android 内存溢出和内存泄漏的问题