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);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。