OKHttp的使用学习
最近实际项目需要处理网络请求(一般是个app都会有的),于是接触了okhttp,目前也就刚刚会使用的程度,不过还是总结一下吧,个人学习的理解不喜勿喷哈。
介绍就不多说了,它就是一个Android用来请求网络的第三方类库,开源的,是目前非常火的一款轻量级HTTP框架,由Square公司开发。
好了废话少说,下面直接上使用说明,我使用的是OKHttp3,就以OKHttp3为例子,因为是提取出来的单独demo,可能有的变量类名没有完全修改对,可能有名字不对的低级错误欢迎指正。
导入方法
在gradle里导入就行了
dependencies里添加这一行完成导入
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
GET方法
同步:
public void getOkHttpByExeCute(final String url){
new Thread(new Runnable() {
@Override
public void run() {
try {
//创建OkHttpClient实例
OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)
.build();
//创建Request
Request request = new Request.Builder().url(url).build();
Call call = okHttpClient.newCall(request);
//获取Response响应
final Response response = call.execute();
if (response.isSuccessful()) {
//UI操作在回到主线程执行
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext,response.code() + response.message() + "",Toast.LENGTH_SHORT).show();
}
});
}
}catch (Exception e) {
e.printStackTrace();
}
}
});
}
异步:
异步请求不需要开启新线程,只需要将回调在子线程中执行
public void getOkHttpByEnqueue(final String url,final Context context){
try {
//创建OkHttpClient实例
OkHttpClient okHttpClient =new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)
.build();
//创建Request
Request request =new Request.Builder().url(url).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 {
if(response.isSuccessful()){
//本部分在子线程执行
//UI操作在回到主线程执行
final Response response2 = response;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();
}
});
}
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
POST方法
post键值对
//post异步请求发送键值对
public static void PostMapByEnqueue (String url, Map map, Callback callback,final Context context) {
FormBody.Builder builder =new FormBody.Builder();
//遍历集合
for (String key : map.keySet()) {
builder.add(key, map.get(key));
}
//创建Request
Request request =new Request.Builder().url(url).post(builder.build()).build();
Call call =getOkHttpClient().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response)throws IOException {
if(response.isSuccessful()){
//子线程执行
//UI操作在回到主线程执行
final Response response2 = response;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
post JSON数据
//post异步请求发送json数据
public static void PostJson(String url, String string, Callback callback,final Context context) {
MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,
RequestBody body = RequestBody.create(JSON, string);
//创建Request
Request request =new Request.Builder().url(url).post(body).build();
Call call =getOkHttpClient().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response)throws IOException {
if(response.isSuccessful()){
//子线程执行
//UI操作在回到主线程执行
final Response response2 = response;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
okhttp实现下载功能
这一步在回调Callback中执行,原理理解同上,将onResponse中的子线程操作具体为下载就行了,下载功能原理是从Response中获取输入流对象实现文件下载
//Okhttp实现下载功能(json数据同理)
public static void download(String url, Map map, Callback callback, final Context context, final String pathStr) {
FormBody.Builder builder =new FormBody.Builder();
//遍历集合
for (String key : map.keySet()) {
builder.add(key, map.get(key));
}
//创建Request
Request request =new Request.Builder().url(url).post(builder.build()).build();
Call call =getOkHttpClient().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response)throws IOException {
if(response.isSuccessful()){
//子线程执行
try{
InputStream is = response.body().byteStream();// 在Response中获取输入流对象
File dir =new File(pathStr);
if (!dir.exists()){
dir.mkdirs();
}
File file =new File(dir, pathStr);
FileOutputStream fos =new FileOutputStream(file);
byte[] buf =new byte[1024*8];
int len =0;
while ((len = is.read(buf)) != -1){
fos.write(buf, 0, len);
}
fos.flush();//file下载完成
}catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
进一步的封装
实际开发中,肯定一堆不同的地方要用到网络请求,我们不可能每一次都写一个post,get请求。为了进一步方便使用,可以考虑封装成一个工具类,我的思路如下:
首先定义获取的数据类,ResponseResult
public class ResponseResult {
private int status;
private Stringmsg;
private Objectdata;
public ResponseResult(int status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public ResponseResult() {
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public StringgetMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public ObjectgetData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
然后自定义回调类,ResponseCallBack
在这里为了更好转换返回的json数据,我们需要导入fastjson这个类库,解析json非常方便实用,当然这就又是另一部分内容了,这里就一笔带过不做详细介绍。
导入方法:
gradle里加入这一行完成导入
implementation"com.alibaba:fastjson:1.2.47"
好的回来继续写ResponseCallBack回调
public abstract class ResponseCallBack Callback {
private Handlerhandler = HttpRequestHandler.getInstance().getHandler();
//主线程处理
public abstract void onUi(HttpResult result);
//主线程处理
public abstract void onFailed(Call call, IOException e);
@Override
public void onFailure(final Call call, final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
onFailed(call, e);
}
});
}
@Override
public void onResponse(Call call, Response response)throws IOException {
final String result = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
onUi(JSON.parseObject(result, ResponseResult .class));
}
});
}
}
接下来写重点,okhttp的工具类:OkHttpUtil
public class OkHttpUtil {
private static OkHttpUtil okHttpUtil =null;
private OkHttpUtil() {
}
public static OkHttpUtil getInstance() {
if (okHttpUtil ==null) {
//加同步安全
synchronized (OkHttpUtil.class) {
if (okHttpUtil ==null) {
okHttpUtil =new OkHttpUtil();
}
}
}
return okHttpUtil;
}
private static OkHttpClient okHttpClient =null;
public synchronized static OkHttpClient getOkHttpClient() {
if (okHttpClient ==null) {
okHttpClient =new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)
.build();
}
return okHttpClient;
}
private static Handler mHandler =null;
public synchronized static Handler getHandler() {
if (mHandler ==null) {
mHandler =new Handler();
}
return mHandler;
}
public static void doPost(String url, Map<String, String> map, Callback callback) {
FormBody.Builder builder =new FormBody.Builder();
//遍历集合
for (String key : map.keySet()) {
builder.add(key, map.get(key));
}
//创建Request
Request request =new Request.Builder().url(url).post(builder.build()).build();
Call call =getOkHttpClient().newCall(request);
call.enqueue(callback);
}
public static void doPost(String url, String string, Callback callback) {
MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,
RequestBody body = RequestBody.create(JSON, string);
//创建Request
Request request =new Request.Builder().url(url).post(body).build();
Call call =getOkHttpClient().newCall(request);
call.enqueue(callback);
}
}
最后是使用,这里只举post键值对的例子
private static int GET_OK = 0//获取数据成功,实际数值根据项目定
public void getHttpData(String key,String value,String url){
final Map map =new HashMap();
map.put(key, value);
OkHttpUtil.getInstance().doPost(url, map, new ResponseCallBack() {
@Override
public void onUi(ResponseResult result) {
if (result.getStatus() ==GET_OK) {
//主线程执行操作
}
}
@Override
public void onFailed(Call call, IOException e) {
//主线程执行操作
}
});
}
封装完成,收工~