android网络请求是个耗时的操作,一定要在子线程中运行,添加网络权限,目前有很多流行的网络框架。比如okhttp,volley,xutils等等。今天主要介绍okhttp的使用,后续分享给多,比如socket网络请求,文件上传下载。
android网络请求是个耗时的操作,一定要在子线程中运行,添加网络权限,目前有很多流行的网络框架。比如okhttp,volley,xutils等等。今天主要介绍okhttp的使用,后续分享给多,比如socket网络请求,文件上传下载。
一,HTTP协议的主要特点 HTTP协议的主要特点可概括如下: 1.支持客户/服务器模式。 2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。 3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。 4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。 5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。 详见原文:HTTP协议详解(真的很经典)
二,OKHttp介绍 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。
okhttp的主要特点:
HTTP/2支持共享一个socket,发送多个请求给相同的主机。
连接池减少了请求的潜在因素。
明显的GZIP压缩下载大小。
响应缓存避免网络重复请求。
确保所有的网络请求只有一个OkHttpClient实例,可以用单例模式。也可以如下:1
public static OkHttpClient okHttpClient = new OkHttpClient();
okhttp发送请求,封装的方法,必须在子线程运行。另外回调方法是在子线程中,要更新UI必须在主线程,自己处理。下面的方法中的OkHttpClient实例统一用上面生成的。
三,okhttp发送get请求 演示基本的用法,不懂的地方可以github下载源码研究。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 "" ;
}
四,OKHttp构建RequestBody 发送post的请求,比较普遍。无论有一个参数,多个参数,或者文件上传,都可以构建特定的RequestBody发送请求。
1.发送一个键值对。 1
RequestBody requestBody = RequestBody.create(MediaType.parse("UTF-8" ),"param=value" );
2.发送多个参数,构建表单一样的请求参数。 1
2
3
4
RequestBody requestBody = new FormBody.Builder()
.add("param1" , "value1" )
.add("param12" , "value2" )
.build();
3. post json字符串 1
2
MediaType JSON = MediaType.parse("application/json; charset=utf-8" );
RequestBody body = RequestBody.create(JSON, json);
4. 文件上传 MediaType,文件类型标示,通常”application/octet-stream”就可以,比如jpg图片,可以MediaType.parse(“image/jpg”)。表单参数根据项目需要自行调整。1
2
3
4
final MediaType mediaType = MediaType.parse("application/octet-stream" );
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MediaType.parse("multipart/form-data" ));
builder.addFormDataPart("name" , fileName);
builder.addFormDataPart("file" , fileName, RequestBody.create(mediaType, uploadFile));
五,发送的post请求的方法 1
2
3
4
5
6
7
8
9
10
11
12
13
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);
}
}
六,总结 okhttp是目前比较流行的网络框架,开源项目,本文介绍了本人一些常用的用法,不到之处望留言指出。对比了一些网络框架,还是挺赞的。 有时间再研究研究源码,未完待续,欢迎交流,杜乾,Dusan,Q 291902259。 真实案例,加入登陆,返回的json数据如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{"status" :1 ,"msg" :"\u83b7\u53d6\u7528\u6237\u6210\u529f" ,"data" :{"uid" :"1" ,"username" :"zhiwei" ,"nickname" :"\u738b\u5fd7\u4f1f" ,"sex" :"1" ,"phone" :"13315211535" ,"avatar" :"http:\/\/gehua.sexhelp.cn\/Uploads\/2016-04-18\/5714ee067a0fb.png" ,"job_number" :"181818" }}
private static final String TAG = DuQianTest.class.getSimpleName();
```
``` java
public static void testLogin () {
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("device_mark" , "869085024277783" )
.add("uid" , "1" )
.build();
Request request = new Request.Builder()
.url("http://gehua.sexhelp.cn/AppInterface/User/getUserInfoInterface.html" )
.post(requestBody)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure (Call call, IOException e) {
LogUtils.debug(TAG,"error= " +e.toString());
}
@Override
public void onResponse (Call call, Response response) throws IOException {
boolean successful = response.isSuccessful();
if (successful) {
final String result = response.body().string();
LogUtils.debug(TAG,"result= " +result);
}
}
});
}
unicode解码(unicode编码转中文)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
* unicode解码(unicode编码转中文)
* @param theString
* @return
*/
public static String unicodeDecode (String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (int x = 0 ; x < len;) {
aChar = theString.charAt(x++);
if (aChar == '\\' ) {
aChar = theString.charAt(x++);
if (aChar == 'u' ) {
int value = 0 ;
for (int i = 0 ; i < 4 ; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
value = (value << 4 ) + aChar - '0' ;
break ;
case 'a' :
case 'b' :
case 'c' :
case 'd' :
case 'e' :
case 'f' :
value = (value << 4 ) + 10 + aChar - 'a' ;
break ;
case 'A' :
case 'B' :
case 'C' :
case 'D' :
case 'E' :
case 'F' :
value = (value << 4 ) + 10 + aChar - 'A' ;
break ;
default :
throw new IllegalArgumentException(
"Malformed \\uxxxx encoding." );
}
}
outBuffer.append((char ) value);
} else {
if (aChar == 't' )
aChar = '\t' ;
else if (aChar == 'r' )
aChar = '\r' ;
else if (aChar == 'n' )
aChar = '\n' ;
else if (aChar == 'f' )
aChar = '\f' ;
outBuffer.append(aChar);
}
} else
outBuffer.append(aChar);
}
return outBuffer.toString();
}