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对象来进行网络连接。
publicvoiddoGet(Viewview) { Request.Builderbuilder=newRequest.Builder(); Requestrequest=builder.get().url(urlString+"userName=pby&userPassword=123").build(); CallnewCall=mOkHttpClient.newCall(request); //newCall.execute() newCall.enqueue(newCallback(){ @Override publicvoidonFailure(Requestrequest,IOExceptione){ L.e("失败了"); } @Override publicvoidonResponse(Responseresponse)throwsIOException{ Stringstring=response.body().string(); L.e(string); } }); }
2、Okhttp的Post请求
Post请求与get请求有些不一样。get请求主要的功能是从服务器上获取数据,而Post请求则是向服务器提交数据。
publicvoiddoPost(Viewview) { FormEncodingBuilderrequestBodyBuilder=newFormEncodingBuilder(); RequestBodyrequestBody=requestBodyBuilder.add("userName","pby").add("userPassword","123").build(); Request.Builderbuilder=newRequest.Builder(); Requestrequest=builder.url(urlString).post(requestBody).build(); CallnewCall=mOkHttpClient.newCall(request); executeCall(newCall); }
3、服务器端接收客户端传过来的字符串
客户端的代码:
publicvoiddoPostString(Viewview) { RequestBodyrequestBody=RequestBody.create(MediaType.parse("text/plain;charset=utf-8"),"{name=pby,password=1234}"); Request.Builderbuilder=newRequest.Builder(); Requestrequest=builder.url(urlString+"doPostString").post(requestBody).build(); CallnewCall=mOkHttpClient.newCall(request); executeCall(newCall); }
服务器端的代码:
publicStringdoPostString()throwsIOException { HttpServletRequestrequest=ServletActionContext.getRequest(); ServletInputStreaminputStream=request.getInputStream(); StringBuildersb=newStringBuilder(); intlen=0; byte[]buff=newbyte[1024]; while((len=inputStream.read(buff))!=-1) { sb.append(newString(buff,0,len)); } System.out.println(sb.toString()); returnnull; }
服务器端如果要接收客户端的数据,则需要接收request;如果服务器端想要给客户端传数据,则需要通过response来传递。
4、使用post方式进行文件的传输
客户端的代码
publicvoiddoPost(Viewview) { FormEncodingBuilderrequestBodyBuilder=newFormEncodingBuilder(); RequestBodyrequestBody=requestBodyBuilder.add("userName","pby").add("userPassword","123").build(); Request.Builderbuilder=newRequest.Builder(); Requestrequest=builder.url(urlString+"login").post(requestBody).build(); CallnewCall=mOkHttpClient.newCall(request); executeCall(newCall); }
关于选择文件的代码--抄袭网络上的代码,并不是自己写的
privatevoidshowFileChooser(){ Intentintent=newIntent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); try{ startActivityForResult(Intent.createChooser(intent,"SelectaFiletoUpload"),1); }catch(android.content.ActivityNotFoundExceptionex){ Toast.makeText(this,"PleaseinstallaFileManager.",Toast.LENGTH_SHORT).show(); } } @Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ switch(requestCode){ case1: if(resultCode==RESULT_OK){ //GettheUrioftheselectedfile Uriuri=data.getData(); Stringpath=FileUtils.getPath(this,uri); if(path!=null) { postFile(path); } } break; } super.onActivityResult(requestCode,resultCode,data); }
在进行这个的操作的时候,一定要记住增加读和写的权限,否则会上传失败的。
服务器端的代码
publicStringdoPostFile()throwsIOException { HttpServletRequestrequest=ServletActionContext.getRequest(); ServletInputStreaminputStream=request.getInputStream(); Stringdir=ServletActionContext.getServletContext().getRealPath("files"); Filefile=newFile(dir,"abc.jpg"); FileOutputStreamfos=newFileOutputStream(file); intlen=0; byte[]buff=newbyte[1024]; while((len=inputStream.read(buff))!=-1) { fos.write(buff,0,len); } fos.flush(); fos.close(); returnnull; }
上面显示的files文件,在Tomcat的webapps下的工程名名文件下的fies文件夹(才开始是没有这个文件夹的,需要手动自己创建)。
5.使用Post方式来上传文件
客户端代码:
privatevoidupLoadFile(Stringpath) { Filefile=newFile(path); if(!file.exists()) { return; } MultipartBuildermultipartBuilder=newMultipartBuilder(); RequestBodyrequestBody=multipartBuilder.type(MultipartBuilder.FORM) .addFormDataPart("userName","pby") .addFormDataPart("userPassword","123") .addFormDataPart("mFile",file.getName(),RequestBody.create(MediaType.parse("application/octet-stream"),file)).build(); //CountingRequestBodycountingRequestBody=newCountingRequestBody(requestBody,newCountingRequestBody.MyListener(){ //@Override //publicvoidonRequestProgress(intbyteWriteCount,intTotalCount){ //L.e(byteWriteCount+"/"+TotalCount); //} //}); Request.Builderbuilder=newRequest.Builder(); //Requestrequest=builder.url(urlString+"doUpLoadFile").post(countingRequestBody).build(); Requestrequest=builder.url(urlString+"doUpLoadFile").post(requestBody).build(); CallnewCall=mOkHttpClient.newCall(request); executeCall(newCall); }
服务器端的代码:
publicStringdoUpLoadFile() { if(mFile==null) { System.out.println(mFileFileName+"isnull.."); returnnull; } Stringdir=ServletActionContext.getServletContext().getRealPath("files"); Filefile=newFile(dir,mFileFileName); try{ FileUtils.copyFile(mFile,file); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } returnnull; }
在上传文件的时候,有一个小细节都注意到:就是Tomcat服务器只允许上传2m以下的文件。要想上传大文件,就必须在struct文件中加一句:
6.上传文件时,进度的显示问题
在写代码的时候我们知道,我们不能直接获得上传文件的进度。因为这些数据都是封装在RequestBody里面的,要想使用只有通过回调接口来实现。
packagecom.example.android_okhttp; importcom.squareup.okhttp.MediaType; importcom.squareup.okhttp.RequestBody; importjava.io.IOException; importokio.Buffer; importokio.BufferedSink; importokio.ForwardingSink; importokio.Okio; importokio.Sink; /** *Createdby前世诀别的一纸书on2017/3/5. */ publicclassCountingRequestBodyextendsRequestBody{ privateRequestBodydelegate=null; privateMyListenermListener=null; privateCountingSinkmCountSink=null; publicinterfaceMyListener { voidonRequestProgress(intbyteWriteCount,intTotalCount); } publicCountingRequestBody(RequestBodyrequestBody,MyListenerlistener) { delegate=requestBody; mListener=listener; } @Override publicMediaTypecontentType(){ returndelegate.contentType(); } @Override publicvoidwriteTo(BufferedSinksink)throwsIOException{ mCountSink=newCountingSink(sink); BufferedSinkbs=Okio.buffer(mCountSink); delegate.writeTo(bs); bs.flush(); } privateclassCountingSinkextendsForwardingSink{ privateintbyteWriteCount=0; publicCountingSink(Sinkdelegate){ super(delegate); } @Override publicvoidwrite(Buffersource,longbyteCount)throwsIOException{ super.write(source,byteCount); byteWriteCount+=byteCount; mListener.onRequestProgress(byteWriteCount,(int)contentLength()); } } @Override publiclongcontentLength()throwsIOException{ returndelegate.contentLength(); } }
MultipartBuildermultipartBuilder=newMultipartBuilder(); RequestBodyrequestBody=multipartBuilder.type(MultipartBuilder.FORM) .addFormDataPart("userName","pby") .addFormDataPart("userPassword","123") .addFormDataPart("mFile",file.getName(),RequestBody.create(MediaType.parse("application/octet-stream"),file)).build(); CountingRequestBodycountingRequestBody=newCountingRequestBody(requestBody,newCountingRequestBody.MyListener(){ @Override publicvoidonRequestProgress(intbyteWriteCount,intTotalCount){ L.e(byteWriteCount+"/"+TotalCount); } }); Request.Builderbuilder=newRequest.Builder(); Requestrequest=builder.url(urlString+"doUpLoadFile").post(countingRequestBody).build(); //Requestrequest=builder.url(urlString+"doUpLoadFile").post(requestBody).build(); CallnewCall=mOkHttpClient.newCall(request);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。