为啥要学Okhttp3呢,因为Retrofit中用到了,而且它本身也是一个网络框架,不与Retrofit一起用还可以单独用,一石二鸟为啥不学呢。这个相对也比较简单。
一、添加依赖
//Okhttp3,后面的那个依赖如果不添加,有说链接不上数据库的,所以还是加上吧,我没添加没啥问题,保险起见
compile 'com.squareup.okhttp3:okhttp:3.3.0'
compile 'com.squareup.okio:okio:1.7.0'
二、Get请求
这里 注意 注意 回调不是在主线程,更新View的时候要注意啦
这里返回的都是Call,之后在Retrofit中你也会看到的,返回的也是Call
/**
* okHttp的Get请求
*
* call.execute()为同步方法
* call.enqueue(new Callback())为异步方法
*
* OkHttp请求的回调不是主线程,可以用runOnUiThread方法回到主线程
*/
private void okhttpGet() {
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder().url("https://www.baidu.com/").build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("------------>","get请求失败"+e+"当前线程:"+Thread.currentThread().getName());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("------------>","get请求成功"+response.body().string()+"当前线程:"+Thread.currentThread().getName());
}
});
}
三、Post请求
RequestBody的数据格式都要指定Content-Type,常见的有三种:
1、application/x-www-form-urlencoded 数据是个普通表单
下面的例子中用的就是这个,可以看到我用的是FormBody,因为FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded。
2、application/json 数据是个json
创建RequestBody时就不能用FormBody啦,要用RequestBody.create()
MediaType JSON = MediaType.parse("application/json; charset=utf-8"); RequestBody body = RequestBody.create(JSON, "你的json");
3、multipart/form-data 数据里有文件
这个时候还有个新的东东MultipartBody;
如下例子中的image/png还可以换成其他的如multipart/form-data,text/plain; charset=utf-8等
RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) //一定写哈 .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file)) .build();
说明:如果一次上传多个内容,可重复利用addFormDataPart方法
RequestBody body = new MultipartBody.Builder().addFormDataPart("","",RequestBody.create(MediaType.parse(""),bytes)).addFormDataPart("","",RequestBody.create(MediaType.parse(""),bytes)).build();
综上:okhttp,还有两种requestBody,一个是FormBody,一个是MultipartBody,前者以表单的方式传递简单的键值对,后者以POST表单的方式上传文件可以携带参数
private void okhttpPost() {
//得到okHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//得到requestBody对象,用来承载参数
RequestBody requestBody = new FormBody.Builder().add("telephone", "15811470200").add("password", "123456").build();
//得到request对象,设置请求时的URL、头,参数等--->参数是在这设置的哦
Request request = new Request.Builder().url("http://www.xxxx/api/rest/login")
.post(requestBody)//参数
.addHeader("xxxxxx","ssssss")//可以添加多个头
.addHeader("ddddd","ssssss")
.build();
//得到call对象
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 {
Log.e("------------>", "response post" + response.body().string());
}
});
}
四、上传文件
/**
* 上传文件,可以是byte数组,也可以是file文件
*
* 如下例子:上传文件同时还需要传其他类型的字段
*/
private void okhttpPostFile(){
File file = new File("");
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("telephone","15811470299")
.addFormDataPart("headimage","imageName",RequestBody.create(MediaType.parse("image/png"),file)).build();
Request request = new Request.Builder().url("https://www.baidu.com").post(requestBody).addHeader("sss","sss").build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("-------------->","e"+e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("-------------->","response"+response.body().string());
}
});
}
五、下载文件
/**
* 下载文件
*/
private void okhttpDownFile(){
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png").build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//获取流
InputStream inputStream = response.body().byteStream();
Log.e("-------------->","length"+response.body().contentLength()+"当前线程:"+Thread.currentThread().getName());
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
//因为回调不是主线程,要更新页面就要回到主线程
runOnUiThread(new Runnable() {
@Override
public void run() {
ImageView imageView = new ImageView(OkHttp3Activity.this);
imageView.setImageBitmap(bitmap);
((RelativeLayout)findViewById(R.id.activity_ok_http3)).addView(imageView);
}
});
}
});
}
六、设置请求时间、缓存大小
//设置超时时间和缓存
private void okhttpSetTimeOutCache(){
long cacheSize = 1024*1000*1000;
OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.readTimeout(15,TimeUnit.SECONDS)
.cache(new Cache(getExternalCacheDir().getAbsoluteFile(),cacheSize))
.build();
}
七、设置Cookie
private void okhttpCookie(){
final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
@Override
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
cookieStore.put(httpUrl.host(), list);
}
@Override
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
List<Cookie> cookies = cookieStore.get(httpUrl.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
}
八、设置请求头
看一看到两种方法,一个是addHeader(),一个是header(),两者区别:
1、在设置 HTTP 头时:
使用 header(name, value) 方法来设置 HTTP 头的唯一值。对同一个 HTTP 头,多次调用该方法会覆盖之前设置的值。
使用 addHeader(name, value) 方法来为 HTTP 头添加新的值。
/**
* okhttp添加请求头
*/
private void okhttpAddHead() {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://www.xxxx/api/rest/session").addHeader("xxxx","xxxxx").header("sssss", "sssss").build();
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 {
Log.e("------------>", "response add" + response.body().string());
Log.e("------------>", "response add" + response.message() + response.code());
Log.e("------------>", "response add" + response.headers());//得到所有的头(服务器的头)
}
});
}
参考文档
(http://www.cnblogs.com/yjpjy/p/5415778.html)