快速使用
- 添加依赖
- 添加权限
1
<uses-permission android:name="android.permission.INTERNET" />
get使用
1 | String url = "https://www.baidu.com"; |
OkHttpClient是创建一个连接,并且设置了连接超时时间和读取超时时间,以及写入超时时间
Request是构造了一个请求
- get是请求方式
- url是请求的url
- addHeader添加header
其中成功的回掉中有一个response参数,他是服务器返回的response
- .body()获取response的body部分的值,通常调用.body().string()获取具体内容经过我测试,body().string()方法使用一次后再次使用会报错,所以最好先取出来字符串然后进行操作
- .isRedirect()判断是不是重定向,其实就是判断状态码是不是重定向的状态码
- .isSuccessful()判断是不是获取成功了,其实就是判断状态码是不是成功的200
- enqueue()是异步调用,如果涉及到更新ui,应该使用runOnUiThread或者其他的线程通信方法
post请求
form请求
1 | RequestBody requestBody = new FormBody.Builder() |
只需要用FromBody实例化一个RequestBody,然后构建request时候把get()改成post(requestBody)即可
json方式请求
post请求和上面一样,不同的是创建RequestBody的方法1
2String json = "{\"username\":\"zhangsan\"}";
RequestBody requestBody = RequestBody.create(MediaType.get("application/json"),json);
拦截器
Okhttp-wiki 之 Interceptors 拦截器
拦截器就是拦截网络请求与响应
1 | public class MyInterceptor implements Interceptor { |
添加应用拦截器
1 | OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new MyInterceptor()).build(); |
添加网络拦截器
1 | OkHttpClient client = new OkHttpClient.Builder().addNetworkInterceptor(new MyInterceptor()).build(); |
应用拦截器和网络拦截器的区别
上面的拦截器是应用拦截器,下面的拦截器是网络拦截器
网络拦截器能拦截所有的网络请求,应用拦截器只能拦截应用发出和最后收到的请求和响应
打个比方:
访问a地址,a地址会重定向到b
那么此时网络拦截器能拦截到发送到a的request和返回a的response和发送给b的request和b返回的response
应用拦截器只会拦截到发送给a的request和b返回的response
文件下载
简单方式
和上面get方式差不多,只不过不是获取response.body().string(),而是获取response的字节流,通过字节流写入到文件中
先加入文件读写的权限1
2<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
1 | OkHttpClient client = new OkHttpClient.Builder() |
其中还调用了设置了一个progressBar显示长度
使用拦截器获取下载进度
写一个接口,设置progress的值,让activity实现这个接口1
2
3
4public interface ProgressListenere {
void sendProgress(int i);
void done();
}
重写ResponseBody,在这里面获取下载的进度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
46public class MyResponseBody extends ResponseBody {
private ResponseBody mResponseBody;
private BufferedSource mBufferedSource;
private ProgressListenere mProgressListenere;
public MyResponseBody(ResponseBody mResponseBody, ProgressListenere mProgressListenere) {
this.mResponseBody = mResponseBody;
this.mProgressListenere = mProgressListenere;
}
public MediaType contentType() {
return mResponseBody.contentType();
}
public long contentLength() {
return mResponseBody.contentLength();
}
public BufferedSource source() {
if(mBufferedSource==null){
mBufferedSource=Okio.buffer(getSource(mResponseBody.source()));
}
return mBufferedSource;
}
private Source getSource(Source source){
return new ForwardingSource(source) {
long allSize=0;
long sum=0;
public long read(Buffer sink, long byteCount) throws IOException {
if(allSize==0){
allSize = contentLength();
}
long len = super.read(sink, byteCount);
sum+=(len>0?len:0);
int progress=(int)(sum*100/allSize);
if(len==-1){
mProgressListenere.done();
}else{
mProgressListenere.sendProgress(progress);
}
return len;
}
};
}
}
mainactivity中和上面差不多,只不过设置进度条的那部分不用写了,然后个构建client的时候要写一个网络拦截器,里面加载刚刚写的ResponseBody1
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
56OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response.newBuilder().body(new MyResponseBody(response.body(),MainActivity.this)).build();
}
})
.build();
String url = "https://www.imooc.com/mobile/mukewang.apk";
Request request = new Request.Builder().get()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
Log.e(TAG, "失败了: ", e);
}
public void onResponse(Call call, Response response) throws IOException {
writeFile(response);
}
});
private void writeFile(Response response) {
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
File file = new File(filePath, "mukewang.apk");
try {
inputStream = response.body().byteStream();
fileOutputStream = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes,0,len);
}
fileOutputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
处理cookies
构建client的时候调用cookieJar方法实现一个CookieJar,saveFromResponse是用于保存网页上传回来的List1
2
3
4
5
6
7
8
9
10
11
12OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
}
public List<Cookie> loadForRequest(HttpUrl url) {
return null;
}
})
.build();
如果cookie为空,返回一个空的list,不能返回null
如果想要保持session,则需要保存cookie中对应的sessionid即可
设置缓存
1 | int cachesize = 10*1024*1024; |
之前写的Java使用okhttp3
使用get访问url,使用json和text的方式posturl
要引入okhttp和okio还有阿里巴巴的fastjson的jar1
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
70
71
72
73import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import com.alibaba.fastjson.JSONObject;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class HttpUtils {
private static OkHttpClient client = new OkHttpClient();
public static String get(String url) throws IOException {
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
// data例子:a=b&=c
public static String Posttext(String url, String data) {
String[] datas = data.split("&");
FormBody.Builder builder = new FormBody.Builder();
for (String dataa:datas) {
builder.add(dataa.split("=")[0],dataa.split("=")[1]);
}
RequestBody requestBody = builder.build();
return Post(url,requestBody);
}
//data例子 {a:b,c:d}
public static String Postjson(String url,String json) {
FormBody.Builder builder = new FormBody.Builder();
JSONObject jsonobject = JSONObject.parseObject(json);
Set<String> keySet = jsonobject.keySet();
Iterator<String> it = keySet.iterator();
while(it.hasNext()) {
String a = it.next();
String b = jsonobject.getString(a);
builder.add(a, b);
}
RequestBody requestBody = builder.build();
return Post(url,requestBody);
}
public static String Post(String url,RequestBody requestBody) {
String result = null;
Request request = new Request.Builder().url(url).post(requestBody).build();
try {
Response response = client.newCall(request).execute();
result = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) throws IOException {
System.out.println(get("http://localhost:8080/Qcb/FriendZoneServlet"));
String json = "{\"context\":\"ccc\",\"icon\":\"aaaa\",\"name\":\"bbb\"}";
System.out.println(Postjson("http://localhost:8080/Qcb/FriendZoneServlet", json));
System.out.println(Posttext("http://localhost:8080/Qcb/FriendZoneServlet", "icon=abc&name=def&context=ghi"));
}
}