大佬教程收集整理的这篇文章主要介绍了android okhttp的基础使用【入门推荐】,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
这篇文章主要总结Android著名网络框架-okhttp的基础使用,后续可能会有关于他的高级使用。
okhttp是什么
okhttp是Android端的一个http客户端,其基础功能相当于Android自带的httpURLConnection和Apache http Client,但他却比自带的2个http客户端优越很多,一者是写法简单,二者okhttp处理很多网络复杂问题,如会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,Okhttp会自动尝试下一个IP。Okhttp还处理了代理服务器问题和SSL握手失败等等很多问题。关于第二者,这篇文章不讨论。
okhttp的导入
Gradle导入
okhttp基础使用
这里我们主要介绍简单的使用,介绍内容如下
get请求
get请求分为同步get和异步get,两者的区别主要get的方式是工作在另一个线程还是工作在本线程。请求的方式大同小异。
private OkhttpClient client = new OkhttpClient();
这个是最简单的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 GMT Content-Type: text/html; charset=utf-8 transfer-encoding: chunked Connection: Keep-Alive Vary: Accept-Encoding Set-Cookie: BAIDUID=A323EC9BF678C0EB78E20741FD71211B:FG=1; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: BIDUPSID=A323EC9BF678C0EB78E20741FD71211B; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: PSTM=1460957023; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-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.com P3P: CP=" OTI DSP COR IVA OUR IND COM " Cache-Control: private Cxy_all: baidu+2db7793e0e32b9f6c20be8f623e1ae43 Expires: Mon,18 Apr 2016 05:22:55 GMT X-Powered-By: HPHP Server: BWS/1.1 X-UA-Compatible: IE=Edge,chrome=1 BDPAGETYPE: 1 BDQID: 0xfacc6fc10004ca96 BDUSERID: 0 Okhttp-Sent-Millis: 1460957021226 Okhttp-Received-Millis: 1460957021430
响应报文的实体可以通过response.body().String()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。
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的方法
@H_376_47@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) { FilenameR_205_11845@ap filenameR_205_11845@ap = URLConnection.getFilenameR_205_11845@ap(); String contentTypeFor = filenameR_205_11845@ap.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'
则我们可以简单的构建这样的一个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的基础使用【入门推荐】所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。