这篇文章主要总结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请求
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 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()。
异步的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", "android").
header("Content-Type", "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, String filename, 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, RequestBody body) {
return addPart(Part.create(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,0,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第三方HTTP网络支持包OkHttp的基础使用教程
# Android使用okHttp(get方式)下载图片
# 详解Android中使用OkHttp发送HTTP的post请求的方法
# Android中Retrofit+OkHttp进行HTTP网络编程的使用指南
# Android M(6.x)使用OkHttp包解析和发送JSON请求的教程
# 使用Android的OkHttp包实现基于HTTP协议的文件上传下载
# Android的HTTP扩展包OkHttp中的缓存功能使用方法解析
# Android App开发中HTTP扩展包OkHttp的入门使用指南
# Android中使用OkHttp包处理HTTP的get和post请求的方法
# Android中的Retrofit+OkHttp+RxJava缓存架构使用
# 的是
# 键值
# 说了
# 可以用
# 你想
# 我们可以
# 可以通过
# 这篇文章
# 自带
# 来实现
# 官网
# 移除
# 都是
# 客户端
# 这是
# 您的
# 实现了
# 构建一个
# 上传
# 这一
相关文章:
如何在香港免费服务器上快速搭建网站?
如何打造高效商业网站?建站目的决定转化率
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
如何在景安服务器上快速搭建个人网站?
开源网站制作软件,开源网站什么意思?
如何获取开源自助建站系统免费下载链接?
网站设计制作企业有哪些,抖音官网主页怎么设置?
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
如何在阿里云虚拟主机上快速搭建个人网站?
建站主机与虚拟主机有何区别?如何选择最优方案?
焦点电影公司作品,电影焦点结局是什么?
简单实现Android验证码
内部网站制作流程,如何建立公司内部网站?
建站之星如何保障用户数据免受黑客入侵?
可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
独立制作一个网站多少钱,建立网站需要花多少钱?
高防服务器:AI智能防御DDoS攻击与数据安全保障
如何挑选高效建站主机与优质域名?
建设网站制作价格,怎样建立自己的公司网站?
如何在阿里云购买域名并搭建网站?
北京网站制作公司哪家好一点,北京租房网站有哪些?
建站之星如何快速更换网站模板?
电脑免费海报制作网站推荐,招聘海报哪个网站多?
青浦网站制作公司有哪些,苹果官网发货地是哪里?
如何选择CMS系统实现快速建站与SEO优化?
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
娃派WAP自助建站:免费模板+移动优化,快速打造专业网站
上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?
建站之星如何助力企业快速打造五合一网站?
网站制作的步骤包括,正确网址格式怎么写?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
智能起名网站制作软件有哪些,制作logo的软件?
宝塔建站助手安装配置与建站模板使用全流程解析
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
公司网站制作费用多少,为公司建立一个网站需要哪些费用?
黑客如何通过漏洞一步步攻陷网站服务器?
建站主机选购指南:核心配置优化与品牌推荐方案
如何快速配置高效服务器建站软件?
如何通过VPS建站实现广告与增值服务盈利?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
如何在万网自助建站中设置域名及备案?
制作营销网站公司,淘特是干什么用的?
如何通过商城自助建站源码实现零基础高效建站?
如何用已有域名快速搭建网站?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
如何选择香港主机高效搭建外贸独立站?
如何用好域名打造高点击率的自主建站?
历史网站制作软件,华为如何找回被删除的网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。