android网络请求是个耗时的操作,一定要在子线程中运行,添加网络权限,目前有很多流行的网络框架。比如okhttp,volley,xutils等等。今天主要介绍okhttp的使用,后续分享给多,比如socket网络请求,文件上传下载。
HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
详见原文:HTTP协议详解(真的很经典)
An HTTP & HTTP/2 client for Android and Java applications. For more information see the website and the wiki.前往OkHttp官网
使用okhttp很简单,它的请求/响应 API设计,运用了流利的builder,确保方式多样而又固定,支持异步请求和回调。它支持android 2.3或以上,jdk版本要求不低于1.7。
确保所有的网络请求只有一个OkHttpClient实例,可以用单例模式。也可以如下:
public static OkHttpClient okHttpClient = new OkHttpClient();
okhttp发送请求,封装的方法,必须在子线程运行。另外回调方法是在子线程中,要更新UI必须在主线程,自己处理。下面的方法中的OkHttpClient实例统一用上面生成的。
演示基本的用法,不懂的地方可以github下载源码研究。
//OKHTTP GET
public static String get(String url){
Request request = new Request.Builder().url(url).build();
Response response = null;
try {
response = new OkHttpClient().newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
发送post的请求,比较普遍。无论有一个参数,多个参数,或者文件上传,都可以构建特定的RequestBody发送请求。
RequestBody requestBody = RequestBody.create(MediaType.parse("UTF-8"),"param=value");
RequestBody requestBody = new FormBody.Builder()
.add("param1", "value1")
.add("param12", "value2")
.build();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, json);
MediaType,文件类型标示,通常”application/octet-stream”就可以,比如jpg图片,可以MediaType.parse(“image/jpg”)。表单参数根据项目需要自行调整。
final MediaType mediaType = MediaType.parse("application/octet-stream");
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MediaType.parse("multipart/form-data"));
builder.addFormDataPart("description", description);
builder.addFormDataPart("file", fileName, RequestBody.create(mediaType, uploadFile));
//构建请求体
RequestBody requestBody = builder.build();
//使用Request的post方法来提交请求体RequestBody
public static String post(String url, RequestBody requestBody) throws IOException {
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Response response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
先看官方对header和addHeader两种方法的解释:
/** * Sets the header named {@code name} to {@code value}. If this request already has any headers * with that name, they are all replaced. */
public Builder header(String name, String value) {
headers.set(name, value);
return this;
}
/** * Adds a header with {@code name} and {@code value}. Prefer this method for multiply-valued * headers like "Cookie". * * <p>Note that for some headers including {@code Content-Length} and {@code Content-Encoding}, * OkHttp may replace {@code value} with a header derived from the request body. */
public Builder addHeader(String name, String value) {
headers.add(name, value);
return this;
}
意思就是说,header是给已有的请求头设置一个值,
addHeader是添加新的请求头,value的值可以有多个(以英文”,”分开)。例如:
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
LogUtils.debug("Server:"+response.header("Server"));
LogUtils.debug("Date: " + response.header("Date"));
LogUtils.debug("Vary: " + response.headers("Vary"));
}
返回结果:
Server: GitHub.com
Sat, 30 Apr 2016 01:24:48 GMT
Vary: [Accept, Accept-Encoding]
okhttp是目前比较流行的网络框架,开源项目,本文介绍了本人一些常用的用法,不到之处望留言指出。对比了一些网络框架,还是挺赞的。
有时间再研究研究源码,未完待续,欢迎交流,杜乾,Dusan,Q 291902259。