一:回忆一下之前用过的网络请求有哪些:httpURLconnection,httpclient,xutils(xUtils 包含了很多实用的android工具。
xUtils 最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响…
xUitls最低兼容android 2.2 (api level 8)DbUtils模块,ViewUtils模块,HttpUtils模块,BitmapUtils模块)关于xutils以后再分享,今天和大家分享一下okhttp!
二:okhttp功能介绍:
1:get请求
2:post请求
3:http文件上传
4:图片加载
5:支持请求回调,直接返回对象、对象集合
6:支持session的保持
三:okhttp的使用,需要导入倚赖文件
添加 okhttp倚赖:compile ‘com.squareup.okhttp:okhttp:2.4.0’
添加okio倚赖:compile ‘com.squareup.okio:okio:1.5.0’
四:使用教程
(一)http get请求
对了网络加载库,那么最常见的肯定就是http get请求了,比如获取一个网页的内容。
//创建okhttpclient对象
OkHttpClient client = new OkHttpClient();
//创建一个request对象
Request request = new Request.Builder().url("http:******").build();
//new call
Call call = client.newCall(request);
//请求调度
call.enqueue(new Callback() {
//请求失败
@Override
public void onFailure(Call call, IOException e) {
}
//请求成功
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
1:首先创建OKhttpclient对象,参数最起码有个url,还可以通过Request.Builder设置更多的参数比如:header、method等。
2:然后通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()和cancel()等方法。
3:最后,我们希望以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。
okhttp的注意点:
1:okhttp的回调结果是response,所以我们需要得到返回的字符串,所以就要这样写response.body().string()获取;还可以获得返回的二进制字节数组,response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()
看到这,你可能会奇怪,竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等,例如:
@Override
public void onResponse(Call call, Response response) throws IOException {
final String res = response.body().string();
//需要开启子线程,更改UI
runOnUiThread(new Runnable() {
@Override public void run() {
} });
}
我们这里是异步的方式去执行,当然也支持阻塞的方式,上面我们也说了Call有一个execute()方法,你也可以直接调用call.execute()通过返回一个Response。
(二)http post请求
//创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//创建请求体FormEncodingBuilder
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("channelId", "0");
builder.add("startNum", "0");
//创建Request对象
Request request = new Request.Builder().url("http://www.93.gov.cn/93app/data.do?").post(builder.build()).build();
//执行异步请求
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
//回调在子线程
final String string = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i("xxx", string.toString());
}
});
}
});
/*
OKHttp发送网络post请求,返回一个jsonString的模板:
OkHttpClient okHttpClient = new OkHttpClient();
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username", name);
builder.add("pwd", pwd);
//创建一个请求对象
Request request = new Request.Builder()
.url(Constants.URLS.LOGIN_URL)
.post(builder.build())
.build();
//发送请求获取响应
Response response = okHttpClient.newCall(request).execute();
String json = response.body().string();
Gson gson = new Gson();
ResultBean resultBean = gson.fromJson(json, ResultBean.class);
return resultBean;
}
HttpClient发送网络post请求,返回一个jsonString的模板:
HttpClient client = new DefaultHttpClient();
// 创建一个Post请求
HttpPost post = new HttpPost(url);
// 将参数设置到Post请求里面
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", name));
params.add(new BasicNameValuePair("pwd", pwd));
HttpEntity entity = new UrlEncodedFormEntity(params); post.setEntity(entity);// 执行一个Post请求 HttpResponse response = client.execute(post); if (response.getStatusLine().getStatusCode()==200) { InputStream is = response.getEntity().getContent(); BufferedReader reader=new BufferedReader(new InputStreamReader(is)); return reader.readLine(); }
}*/
五:对okhttp进行封装(利用单例模式)
利用的是懒汉单例模式;
/*懒汉 安全 加同步;
私有的静态成员变量,只声明不创建实例,只有在调用的时候才实例化;
提供返回的静态方法
*/
—–utils——-
package com.bawei.test;
import android.os.Environment;
import java.io.File;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class OKhttpUtils {
private static OkHttpClient okHttpClient = null;
OKhttpUtils() {
}
public static OkHttpClient getInstance() {
if (okHttpClient == null) {
//加同步安全
synchronized (OKhttpUtils.class) {
if (okHttpClient == null) {
//判空 为空创建实例
// okHttpClient = new OkHttpClient();
/**
* 和OkHttp2.x有区别的是不能通过OkHttpClient直接设置超时时间和缓存了,而是通过OkHttpClient.Builder来设置,
* 通过builder配置好OkHttpClient后用builder.build()来返回OkHttpClient,
* 所以我们通常不会调用new OkHttpClient()来得到OkHttpClient,而是通过builder.build():
*/
// File sdcache = getExternalCacheDir();
File sdcache = new File(Environment.getExternalStorageDirectory(), "cache");
int cacheSize = 10 * 1024 * 1024;
okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS).build();
}
}
}
return okHttpClient;
}
//get请求
public void Get(String url, Callback callback){
//创建httpclient
OkHttpClient httpClient = getInstance();
//创建request对象
Request request = new Request.Builder().url(url).build();
//创建call
Call call = httpClient.newCall(request);
call.enqueue(callback);
}
//post请求
public void Post(String url, HashMap<String,String> parmas,Callback callback){
OkHttpClient httpClient = getInstance();
//3.x版本post请求换成FormBody 封装键值对参数
FormBody.Builder builder = new FormBody.Builder();
for (String key:parmas.keySet()){
builder.add(key,parmas.get(key));
}
Request request = new Request.Builder().url(url).post(builder.build()).build();
Call call = httpClient.newCall(request);
call.enqueue(callback);
}
}
/**
* post请求上传文件
* 参数1 url
* 参数2 回调Callback
*/
public static void uploadPic(String url, File file, String fileName) {
//创建OkHttpClient请求对象
OkHttpClient okHttpClient = getInstance();
//创建RequestBody 封装file参数
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//创建RequestBody 设置类型等
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", fileName, fileBody).build();
//创建Request
Request request = new Request.Builder().url(url).post(requestBody).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 {
//上传成功回调 目前不需要处理
}
});
}
——–mainactivity———–
package com.bawei.test;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import java.io.IOException;
import java.util.HashMap;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OKhttpUtils utils = new OKhttpUtils();
//get请求
/* utils.Get("http://news-at.zhihu.com/api/4/stories/latest", new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String s = response.body().string();
Looper.prepare();
Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
Looper.loop();
}
});*/
//post请求
String url = "http://www.93.gov.cn/93app/data.do?" + "channelId=" + 0 + "&startNum=" + 0;
HashMap<String, String> map = new HashMap<>();
map.put("channelId", "0");
map.put("startNum", "0");
utils.Post(url, map, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String s = response.body().string();
Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
}
});
}
}
//图片上传
private void uploadPic() {
File file = new File(Environment.getExternalStorageDirectory(), "a.jpg");
String fileName = "a.jpg";
OkHttp3Utils.uploadPic(picUrl, file, fileName);
}