前言
各种各样的网络框架,每次都是上网随便一搜,然后照着写一写最简单的用法,然后下次又遇到需要网络请求的时候,又忘记怎么用了。。。好无奈。所以在这里仔细记录一下,能加深印象和理解。
本文主要讲解的有以下知识点:
- get请求
- post请求
- 基于Http的文件上传
- 文件下载
- 加载图片
- 支持请求回调,直接返回对象,对象集合
- 支持session的保持
使用
老规矩,添加依赖
compile 'com.squareup.okhttp:okhttp:2.4.0'
而因为okhttp内部依赖okio,所以:
compile 'com.squareup.okio:okio:1.5.0'
一.Http Get
1.创建okHttpClient对象
2.构造Request对象(参数至少有url,可以通过Requesr.Builder设置更多的参数)
3.newCall(request),将request对象传入,去构造得到Call对象。也就是将你的请求封装成了任务,既然是,就有cancel
和execute
方法。
4.请求加入调度,enqueue,在回调者中处理请求结果。
//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
final Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();
//new call
Call call = mOkHttpClient.newCall(request);
//请求加入调度
call.enqueue(new Callback()
{
@Override
public void onFailure(Request request, IOException e)
{
}
@Override
public void onResponse(final Response response) throws IOException
{
//String htmlStr = response.body().string();
}
});
我们这里是异步的方式去执行,当然也支持阻塞的方式,上面我们也说了Call有一个execute()
方法,你也可以直接调用call.execute()通过返回一个Response。
注意:在这里onResponse
,并不是运行在UI线程。返回的response
可以转化为:
字符串:response.body().string()
二进制字节数组:response.body().bytes()
输入流(读)inputsream:response.body().byteStream()
二.Http Post携带参数
Post与Get主要是Request的构造不同。通过FormEncodingBuilder,添加多个String键值对,然后去构造RequestBody,最后完成Request的构造。
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username","一期一会");
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
mOkHttpClient.newCall(request).enqueue(new Callback(){});
Post提交json数据
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
f (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
POST提交键值对
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody formBody = new FormEncodingBuilder()
.add("platform", "android")
.add("name", "bug")
.add("subject", "XXXXXXXXXXXXXXX")
.build();
Request request = new Request.Builder()
.url(url)
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
基于Http的文件上传
先介绍一个可以构造RequestBody的Builder,叫做MultipartBuilder(可用于表单上传)
如果想向服务端上传一个键值对username:hy和一个文件,怎么写?看以下代码:
File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"username\""),
RequestBody.create(null, "张鸿洋"))
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"mFile\";
filename=\"wjd.mp4\""), fileBody)
.build();
Request request = new Request.Builder()
.url("http://192.168.1.103:8080/okHttpServer/fileUpload")
.post(requestBody)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback()
{
//...
});
下载文件/下载图片
文件和图片区别就是在得到response.body,如何转换。文件一般是拿到inputStream做写文件操作,而图片是拿到byte[]然后decode成图片
同步Get
若返回的文件较小,可response.body.string
,若文件较大,超过1mb,用流的方式来处理body.
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
异步Get.
在一个工作线程中下载文件,当响应可读时回调Callback接口。读取响应时会阻塞当前线程。OkHttp现阶段不提供异步api来接收响应体。
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Request request, Throwable throwable) {
throwable.printStackTrace();
}
@Override public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
});
}
封装
以上使用,代码都太多了有木有,而且还很难记住用法。
在这里推荐鸿洋大神写的OKhttpUtils工具类。挺好听的,减少了很多代码量,代码也简洁明了。
在as添加依赖即可使用该工具:
compile 'com.zhy:okhttputils:2.6.2'
或者直接添加jar包
嗯。。原来只能上传图片。。
那还是去这里下载吧:
https://github.com/hongyangAndroid/okhttputils
里面还有详细的使用步骤~
下面是我第一次使用okhttp,以表单的形式,同时提交键值对和图片。刚开始接触okhttp,看了很多博客,写出来的提交代码都不成功。后来用okhttpUtils解决了!
public static void uploadImage(String user, String path,String name, String seabillno,final Handler mHandler){
Map<String, String> params = new HashMap<String, String>();
params.clear();
//键值对
params.put("user",user);
params.put("seabillno",seabillno);
params.put("token","dylpda2018");
File file=new File(path);
OkHttpUtils.post()//
.addFile("file", name, file)//图片
.url(URL_UPLOAD_PICTURE)
.params(params)//
.build()//
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String s, int i) {
System.out.println( "onSuccess: "+e);
Message message=Message.obtain();
message.what= Constants.UPLOAD_PIC_SUCCESS;
message.obj=s;
mHandler.sendMessage(message);
System.out.println(s);
}
});
}
参考文章:
https://blog.csdn.net/lmj623565791/article/details/47911083
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html