android okhttp的基础使用【入门推荐】

android okhttp的基础使用【入门推荐】,第1张

概述这篇文章主要总结Android著名网络框架-okhttp的基础使用,后续可能会有关于他的高级使用。

这篇文章主要总结AndroID著名网络框架-okhttp的基础使用,后续可能会有关于他的高级使用。

okhttp是什么

okhttp是AndroID端的一个http客户端,其基础功能相当于AndroID自带的httpURLConnection和Apache http ClIEnt,但他却比自带的2个http客户端优越很多,一者是写法简单,二者okhttp处理很多网络复杂问题,如会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,Okhttp会自动尝试下一个IP。Okhttp还处理了代理服务器问题和SSL握手失败等等很多问题。关于第二者,这篇文章不讨论。

okhttp的导入

Gradle导入

 compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okio:okio:1.6.0'

okhttp基础使用

这里我们主要介绍简单的使用,介绍内容如下

get请求 post请求,参数是键值对 post请求,多种类型的body 文件下载 加入Gson

get请求

get请求分为同步get和异步get,两者的区别主要get的方式是工作在另一个线程还是工作在本线程。请求的方式大同小异。

首先定义一个OkhttpClIEnt对象,如下

private OkhttpClIEnt clIEnt = new OkhttpClIEnt();

然后构建一个Request,构建方式如下:

Request request = new Request.Builder().url("http://www.baIDu.com").build();

这个是最简单的request的构建方式,当然我们可以构建的很复杂。

 Request request = new Request.Builder().    url("http://www.baIDu.com").    addheader("User-Agent","androID").    header("Content-Type","text/HTML; charset=utf-8").    build();

通过addheader和header方法为请求增加请求头部,注意使用header(name,value)可以设置唯一的name、value。如果已经有值,旧的将被移除,然后添加新的。使用addheader(name,value)可以添加多值(添加,不移除已有的)。

同步的get方法,通过clIEnt.newCall(request).execute()方法得到请求的response.

 Response response = okhttpClIEnt.newCall(request).execute();

Okhttp封装了很多处理response的方法,比如response.headers()的得到headers.

headers headers = response.headers(); for (int i = 0; i < headers.size(); i++) {System.out.println(headers.name(i) + ": " + headers.value(i)); }

结果如下:

Date: Mon,18 Apr 2016 05:23:43 GMTContent-Type: text/HTML; charset=utf-8@R_502_1071@: chunkedConnection: Keep-Alivevary: Accept-EnCodingSet-cookie: BAIDUID=A323EC9BF678C0EB78E20741FD71211B:FG=1; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baIDu.comSet-cookie: BIDUPSID=A323EC9BF678C0EB78E20741FD71211B; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baIDu.comSet-cookie: PSTM=1460957023; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baIDu.comSet-cookie: BDSVRTM=0; path=/Set-cookie: BD_HOME=0; path=/Set-cookie: H_PS_PSSID=1434_19672_18281_19690_17948_18205_19558_15952_12257; path=/; domain=.baIDu.comP3P: CP=" OTI DSP COR IVA OUR IND COM "Cache-Control: privateCxy_all: baIDu+2db7793e0e32b9f6c20be8f623e1ae43Expires: Mon,18 Apr 2016 05:22:55 GMTX-Powered-By: HPHPServer: BWS/1.1X-UA-Compatible: IE=Edge,Chrome=1BDPAGETYPE: 1BDQID: 0xfacc6fc10004ca96BDUSERID: 0Okhttp-Sent-Millis: 1460957021226Okhttp-Received-Millis: 1460957021430

响应报文的实体可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。

异步的get请求得到的response方法是通过如下方法

okhttpClIEnt.newCall(request).enqueue(new Callback() {      @OverrIDe      public voID onFailure(Call call,IOException e) {      }        @OverrIDe      public voID onResponse(Call call,Response response) throws IOException {      }    });

在onResponse方法中,执行请求成功的代码,onFailure方法中,执行请求失败的代码,下面给一个完整的异步get的栗子

import androID.os.Bundle;import androID.os.Handler;import androID.support.v7.app.AppCompatActivity;import androID.text.method.ScrollingMovementMethod;import androID.Widget.TextVIEw;import java.io.IOException;import okhttp3.Call;import okhttp3.Callback;import okhttp3.headers;import okhttp3.OkhttpClIEnt;import okhttp3.Request;import okhttp3.Response;public class MainActivity extends AppCompatActivity { private OkhttpClIEnt okhttpClIEnt = new OkhttpClIEnt(); public TextVIEw show; public Handler handler = new Handler(); @OverrIDe protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentVIEw(R.layout.activity_main);  show = (TextVIEw) findVIEwByID(R.ID.show);  show.setMovementMethod(ScrollingMovementMethod.getInstance());  Request request = new Request.Builder().    url("http://www.baIDu.com").    addheader("User-Agent","text/HTML; charset=utf-8").    get().    build();  okhttpClIEnt.newCall(request).enqueue(new Callback() {   @OverrIDe   public voID onFailure(Call call,IOException e) {   }   @OverrIDe   public voID onResponse(Call call,final Response response) throws IOException {    final headers headers = response.headers();    final String str = response.body().string();    handler.post(new Runnable() {     @OverrIDe     public voID run() {      for (int i = 0; i < headers.size(); i++) {       show.append(headers.name(i) + ": " + headers.value(i));       show.append(str);      }     }    });   }  }); }}

其实按照官网说的,回调是发生在response 的headers准备好就发生的,所以有时候请求response的实体部分会发生阻塞。

post请求――键值对为参数。

post请求和get请求除了在构建request上面不同以外,在处理response上面都是一样的,所以下面我们只讨论一下post构建request,当然post也是支持同步post和异步post的,可以参考get方法。

在构建post的request时候,首先用FormBody.Builder去构建request的body部分,栗子如下,当然这是OKhttp3的方法.

FormBody.Builder builder = new FormBody.Builder();  for(int i = 0 ; i < key.size() ;i ++){   builder.add(key.get(i),value.get(i));  }  Requestbody body = builder.build();

builder中add的是要加入的参数键值对。得到要构造的body后用

Request request = new Request.Builder().url(url).post(body).build();

获得请求的request,后面的 *** 作就和get方法是一样的,这里可以参考异步get的栗子,构建一个post的request.下面的写法原封不变。

post请求--多种类型的body

上文已经说了post和get的用法主要在构建不同的request上面,所以接下来我们主要讨论的也是如何构建request.

参考上面,我们首先要创建一个requestbody,我们可以用下面的方式去构建,当然这也是okhttp3的方法

Multipartbody.Builder builder = new Multipartbody.Builder().setType(Multipartbody.FORM);

已表单上传的形式去提交post。我们看一下builder的方法

 /** Add a part to the body. */ public Builder addPart(Requestbody body) {  return addPart(Part.create(body)); } /** Add a part to the body. */ public Builder addPart(headers headers,Requestbody body) {  return addPart(Part.create(headers,body)); } /** Add a form data part to the body. */ public Builder addFormDataPart(String name,String value) {  return addPart(Part.createFormData(name,value)); } /** Add a form data part to the body. */ public Builder addFormDataPart(String name,String filename,Requestbody body) {  return addPart(Part.createFormData(name,filename,body)); }

从这里我们可以看出可以直接用 public Builder addFormDataPart(String name,Requestbody body)上传一个file,最后一个参数是请求的实体,可以通过 Requestbody.create(final MediaType ContentType,final file file) 获得,而MediaType则可以通过下面方法获得

//调用judgeType方法private static final MediaType MEDIA_TYPE = MediaType.parse(judgeType(filename);//judge方法如下private String judgeType(String path) {  filenameMap filenameMap = URLConnection.getfilenameMap();  String ContentTypeFor = filenameMap.getContentTypeFor(path);  if (ContentTypeFor == null) {   ContentTypeFor = "application/octet-stream";  }  return ContentTypeFor; }

由于我后台能力比较渣,这里用一个官网的例子来实现一遍我刚才讨论的方法。

Multipartbody.Builder builder = new Multipartbody.Builder()  .setType(Multipartbody.FORM)  .addFormDataPart("image","logo-square.png",Requestbody.create(MEDIA_TYPE_PNG,new file("website/static/logo-square.png")));Requestbody requestbody = builder.build(); Request request = new Request.Builder()  .header("Authorization","ClIEnt-ID " +"9199fdef135c122")  .url("https://API.imgur.com/3/image")  .post(requestbody)  .build();

当然除了这个方法以外,调用如下方法也是可以的,我们可以利用name和filename自己构造header传上去。

public Builder addPart(headers headers,body))

栗子如下:

builder.addPart(headers.of("Content-disposition","form-data; name=\"" + name + "\"; filename=\"" + filename + "\""),fileBody);

后面的写法和上面类似,这样我们就实现了文件上传的写法。

文件下载

刚才我们上面已经说了,希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。换句话说,文件的下载可以简单的通过get请求,得到相应的response,在把他的实体转换成二进制流写入文件,就是实现了文件的下载。主要的写法就是文件的读写,跟OKhttp关系不大,当然我们也可以用okio来实现文件的读写,这里水平有限就不介绍了。下面给一个简单的例子。

private voID _download(final String url,final String destfileDir,final ResultCallback callback) {  final Request request = new Request.Builder().url(url).build();  final Call call = okhttpClIEnt.newCall(request);  call.enqueue(new Callback() {   @OverrIDe   public voID onFailure(Call call,IOException e) {   }   @OverrIDe   public voID onResponse(Call call,Response response) throws IOException {    inputStream is = null;    byte[] buf = new byte[2048];    int len = 0;    fileOutputStream fos = null;    try {     is = response.body().byteStream();     file file = new file(destfileDir,getfilename(url));     fos = new fileOutputStream(file);     while((len = is.read(buf)) != -1){      fos.write(buf,len);     }     fos.flush();     //....省略后续对已经保存的文件的 *** 作    } catch (IOException e) {     e.printstacktrace();    }finally {     try {      if (is != null) is.close();     } catch (IOException e) {     }     try     {      if (fos != null) fos.close();     } catch (IOException e)     {     }    }   }  }); }

加入Gson

接下来,我们讨论一个很实际的问题,AndroID的网络请求一般不会去请求一个网站的HTML,更多的是请求后台接口的Json文件,所以我们用Gson来处理Json的解析。这一部分和前面就不同了,前面多数讲的是如何构建不同的request来得到response,而对响应的结果,处理都是一致的。但这里主要的写法就是用Gson去处理response,而request的构建则根据上面介绍的方法去构建,无需改变。

Gson的导入

compile 'com.Google.code.gson:gson:2.6.2'

比如我们后台给出的API是这样一个Json文件

{ "status": 0,"intro": "你好","shopname": "byhIEg",  "message": "查询成功",}

则我们可以简单的构建这样的一个Test.java文件,如下所示:

public class Test { /**  * status : 0  * intro : byhIEg  * shopname : byhige  * message : 查询成功  */ private int status; private String intro; private String shopname; private String message; public int getStatus() {  return status; } public voID setStatus(int status) {  this.status = status; } public String getIntro() {  return intro; } public voID setIntro(String intro) {  this.intro = intro; } public String getShopname() {  return shopname; } public voID setShopname(String shopname) {  this.shopname = shopname; } public String getMessage() {  return message; } public voID setMessage(String message) {  this.message = message; }}

在获得到response之后,用如下代码把Json文件解析成result对象。然后调用result对象的get方法就可以得到Json文件中的intro的值和shopname的值,以及status和message.这里就不多介绍了

Test result = new Gson().fromJson(response.body().string,Test.class);

总结

简单介绍了okhttp的使用,对于一些高级用法请关注下篇文章,本人水平有限,如有错误,还望指正。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持编程小技巧!

总结

以上是内存溢出为你收集整理的android okhttp的基础使用【入门推荐】全部内容,希望文章能够帮你解决android okhttp的基础使用【入门推荐】所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存