Okhttp3的使用
在build.gradle 加上依赖
compile 'com.squareup.okhttp3:okhttp:3.8.0'
compile 'com.squareup.okio:okio:1.12.0'
配置文件添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
添加HttpUtil工具类
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.lemonsoft.myapplication.base.MyApplication;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InterfaceAddress;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class HttpUtil {
//请求类型,与服务器保持一致
private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
//public static String BASE_URL = "域名";
public static String BASE_URL = "http://192.168.0.11:8001/api";
public static String DOCUMENT_URL = BASE_URL.replace("api","document");
public static String webBaseurl = BASE_URL.replace("api","phoneweb");
//public static String webBaseurl = " http://192.168.0.2:8080/";
private static Handler mainHandler = new Handler(Looper.getMainLooper());
private static OkHttpClient okHttpClient;
private static String TAG = "OKHTTP-----";
public interface HttpCallBack{
//1的时候我们需要的是data,因此返回的是json类型的字符串,开发者可在回调里面根据需求转换类型
default void onSuccess(String json){};
//2的时候我们是收到了一个通知表示刚才的操作成功了,例如评论校园圈,返回2执行某个接口,在接口中我们刷新评论列表
default void onNotice(){};
//0的时候是后台代码捕获到的可以控制的异常,典型的是密码错误!这时直接谈一个toast 密码错误
default void onToast(){};
//3 系统捕获到了未知的异常
default void onCatchError(){};
//系统没有响应,这个地址错了?服务器掉线了?概率很低,不常用
default void onNoResponse(){};
}
/*全局单例*/
private static OkHttpClient getInstance() {
if (okHttpClient == null) {
synchronized (HttpUtil.class) {
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)//10秒连接超时
.writeTimeout(10, TimeUnit.SECONDS)//10m秒写入超时
.readTimeout(10, TimeUnit.SECONDS)//10秒读取超时
//.addInterceptor(new HttpHeaderInterceptor())//头部信息统一处理
//.addInterceptor(new CommonParamsInterceptor())//公共参数统一处理
.build();
}
}
}
return okHttpClient;
}
/**
* @param url url地址
* @param callBack 请求回调接口
*/
public static void get(String url, HttpCallBack callBack) {
commonGet(getRequestForGet(url, null, null), callBack);
}
/**
* @param url url地址
* @param params HashMap<String, String> 参数
* @param callBack 请求回调接口
*/
public static void get(String url, HashMap<String, String> params, HttpCallBack callBack) {
commonGet(getRequestForGet(url, params, null), callBack);
}
/**
* @param url url地址
* @param params HashMap<String, String> 参数
* @param callBack 请求回调接口
* @param tag 网络请求tag
*/
public static void get(String url, HashMap<String, String> params, HttpCallBack callBack, Object tag) {
commonGet(getRequestForGet(url, params, tag), callBack);
}
/**
* @param url url地址
* @param params HashMap<String, Object> 参数
* @param callBack 请求回调接口
*/
public static void post(String url, HashMap<String, Object> params, HttpCallBack callBack) {
commonPost(getRequestForPost(url, params, null), callBack);
}
/**
* @param url url地址
* @param clz 直接传递一个类当参数
* @param callBack 请求回调接口
*/
public static <T> void post(String url, T clz, HttpCallBack callBack) {
commonPost(getRequestForPost(url, clz, null), callBack);
}
/**
* @param url url地址
* @param params HashMap<String, Object> 参数
* @param callBack 请求回调接口
* @param tag 网络请求tag
*/
// TODO
public static void post(String url, HashMap<String, Object> params, HttpCallBack callBack, Object tag) {
commonPost(getRequestForPost(url, params, tag), callBack);
}
/**
* GET请求 公共请求部分
*/
private static void commonGet(Request request, final HttpCallBack callBack) {
if (request == null) return;
Call call = getInstance().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
Log.e(TAG, "Failure--->" + e.getMessage());
callBack.onNoResponse();
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
Log.e(TAG, "Response--->" + response);
if (callBack != null && mainHandler != null && response != null) {
handleResponse(response,callBack);
}
}
});
}
/*
* 处理全局返回值
* */
private static void handleResponse(@NonNull Response response, final HttpCallBack callBack) {
String jsonstr = null;
try {
jsonstr = response.body().string();
Log.d("response", jsonstr);
JSONObject jsonObject = new JSONObject(jsonstr);
int code = jsonObject.getInt("code");
switch (code){
case 0:
mainHandler.post(new Runnable() {
@Override
public void run() {
callBack.onToast();
}
});
Context context = MyApplication.getInstance().getApplicationContext();
Looper.prepare();
Toast.makeText(context, jsonObject.getString("msg"), Toast.LENGTH_SHORT).show();
Looper.loop();
break;
case 1:
final String body = jsonObject.getString("data");
mainHandler.post(new Runnable() {
@Override
public void run() {
callBack.onSuccess(body);
}
});
break;
case 2:
mainHandler.post(new Runnable() {
@Override
public void run() {
callBack.onNotice();
}
});
break;
case 3:
mainHandler.post(new Runnable() {
@Override
public void run() {
callBack.onCatchError();
}
});
break;
default:
break;
}
} catch (IOException e) {
Log.d(TAG, "IOException--->" + e.getMessage());
e.printStackTrace();
} catch (JSONException e) {
Log.d(TAG, "JSONException--->" + e.getMessage());
e.printStackTrace();
}
}
/**
* POST请求 公共请求部分
*/
// TODO
private static void commonPost(Request request, final HttpCallBack callBack) {
if (request == null) return;
Call call = getInstance().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
Log.d(TAG, "Failure--->" + e.getMessage());
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
if (callBack != null && mainHandler != null) {
handleResponse(response,callBack);
}
}
});
}
/*构造post请求Request*/
private static Request getRequestForPost(String url, Map<String, Object> params, Object tag) {
if (params == null) {
params = new HashMap<>();
}
String json = GsonUtil.toJson(params);
Log.d(TAG, "postMap------->"+json);
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);
return getFinalRequest(body,url,tag);
}
/*构造post请求Request*/
// TODO
private static <T> Request getRequestForPost(String url, T clz, Object tag) {
String json = GsonUtil.toJson(clz);
Log.d(TAG, "postMap------->"+json);
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);
return getFinalRequest(body,url,tag);
}
private static Request getFinalRequest(RequestBody body,String url,Object tag){
if (url == null || "".equals(url)) {
return null;
}
Request.Builder builder = new Request.Builder();
if(body!=null){
builder.post(body).url(BASE_URL+url);
}else{
//虽然构建者模式是链式操作,但必须先get在url,要不404错误
builder.get().url(BASE_URL+url);
}
if (tag != null) {
builder.tag(tag);
}
// User user =MyApplication.getUserEntity();
// Log.d(TAG, "Url---构建完毕--->"+url);
// if(user!=null && user.getToken()!=null){
// Log.d(TAG, "userid------------------------->"+user.getId());
// builder.addHeader("token",user.getToken());
// }
return builder.build();
}
/*构造get请求Request*/
private static Request getRequestForGet(String url, HashMap<String, String> params, Object tag) {
String completeUrl = paramsToString(url, params);
return getFinalRequest(null,completeUrl,tag);
}
/*
* get请求地址和参数转化成长字符串
* */
private static String paramsToString(String url, HashMap<String, String> params) {
StringBuilder url_builder = new StringBuilder();
url_builder.append(url);
if (params != null && params.size() > 0) {
url_builder.append("?");
int i=0;
for (Map.Entry<String, String> entry : params.entrySet()) {
i++;
try {
if(i!=1){
url_builder.append("&");
}
//url_builder.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
url_builder.append(entry.getKey()).append("=").append(entry.getValue());
} catch (Exception e) {
e.printStackTrace();
}
}
}
String string= url_builder.toString();
return string;
}
/**
* 根据tag标签取消网络请求
*/
public static void cancelTag(Object tag) {
if (tag == null) return;
for (Call call : getInstance().dispatcher().queuedCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
for (Call call : getInstance().dispatcher().runningCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
}
/**
* 取消所有请求请求
*/
public static void cancelAll() {
for (Call call : getInstance().dispatcher().queuedCalls()) {
call.cancel();
}
for (Call call : getInstance().dispatcher().runningCalls()) {
call.cancel();
}
}
/*
* 地址,上传文件用途,参数,文件地址集合
* */
public static void uploadMultiple (String url, String pic_key, Map<String,String> params,List<String> fileAddress,HttpCallBack callBack){
MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
multipartBodyBuilder.setType(MultipartBody.FORM);
//遍历map中所有参数到builder
if (params != null){
for (String key : params.keySet()) {
multipartBodyBuilder.addFormDataPart(key, params.get(key));
}
}
//遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key
if (fileAddress != null&&fileAddress.size()>0){
for (String address : fileAddress) {
File file = new File(address);
multipartBodyBuilder.addFormDataPart(pic_key, file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file));
}
RequestBody requestBody = multipartBodyBuilder.build();
Request.Builder RequestBuilder = new Request.Builder();
RequestBuilder.url(BASE_URL+url);// 添加URL地址
RequestBuilder.post(requestBody);
Request request = RequestBuilder.build();
Call call = getInstance().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
Log.d(TAG, "Failure--->" + e.getMessage());
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
if (callBack != null && mainHandler != null && response != null) {
handleResponse(response,callBack);
}
}
});
}
}
/*
* 迎合php,只能单图上传,上传文件用途,参数,文件地址集合
* */
public static void upload(File file,HttpCallBack callBack){
try{
if(file==null){
return;
}
if(!file.exists()){
return;
}
compressBitmap(file);
String filename = file.getName();
String[] types = filename.split("\\.");
String type = types[types.length-1];
String img[] = { "bmp","gif", "ief", "jpeg", "pipeg", "svg", "xml", "tiff", "jpg","png"};
boolean flag = false;
for (int i = 0; i < img.length; i++) {
if (img[i].equals(type)) {
flag = true;
break;
}
}
if(!flag){
Looper.prepare();
Toast.makeText(MyApplication.getInstance(), "文件类型不支持", Toast.LENGTH_SHORT).show();
Looper.loop();
return;
}
if(type=="jpg"){
type="jpeg";
}
RequestBody fileBody = RequestBody.create(MediaType.parse("image/"+type), file);
String name = URLEncoder.encode(file.getName(), "utf-8");
//文件名必须得有,相当于key,没有不能识别文件
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file",name ,fileBody)
.build();
Request request = new Request.Builder()
.url(BASE_URL+"Common/upload")
.post(requestBody)
.build();
Call call = getInstance().newCall(request);
Log.d(TAG, "上传------->" + filename);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
Log.d(TAG, "Failure------->" + e.getMessage());
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
if (callBack != null && mainHandler != null && response != null) {
handleResponse(response,callBack);
}
}
});
}catch (Exception e){
e.printStackTrace();
}
}
public static void compressBitmap(File file){
// 数值越高,图片像素越低
int inSampleSize = 1;
int max = 1024*1024*1;
//单位为字节
if(file.length()>max){
while (file.length()/max>2){
max*=2;
inSampleSize*=2;
}
BitmapFactory.Options options = new BitmapFactory.Options();
//采样率
options.inSampleSize = inSampleSize;
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 把压缩后的数据存放到baos中
bitmap.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public interface Finish{
void finish();
}
private static void zhixing(int len,int[] finishcount ,HttpUtil.Finish finish){
finishcount[0]++;
if(finishcount[0]>=len){
finish.finish();
}
}
/*
* 临时弄一个可进行网络请求的方法,当所有的请求全部完毕时才会进行下一步
* */
public static void add(String [] urls,HashMap<String,Object> [] maps,HttpCallBack [] callBacks,HttpUtil.Finish finish){
int len = maps.length;
if(urls.length!=maps.length || maps.length!=callBacks.length){
return;
}
Boolean [] bools = new Boolean[len];
final Response [] responses = new Response[len];
final int[] finishcount = {0};
for(int i=0;i<len;i++){
Request request;
if(maps[i]==null){
//get请求
request = getFinalRequest(null,urls[i],null);
if (request == null) return;
}
else {
String json = GsonUtil.toJson(maps[i]);
Log.d(TAG, "postMap------->" + json);
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);
request = getFinalRequest(body, urls[i], null);
}
Call call = getInstance().newCall(request);
int finalI = i;
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
Log.d(TAG, "Failure--->" + e.getMessage());
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
if (mainHandler != null && response != null) {
String jsonstr = null;
try {
jsonstr = response .body().string();
Log.d("response", jsonstr);
JSONObject jsonObject = new JSONObject(jsonstr);
int code = jsonObject.getInt("code");
switch (code){
case 0:
Context context = MyApplication.getInstance().getApplicationContext();
Looper.prepare();
Toast.makeText(context, jsonObject.getString("msg"), Toast.LENGTH_SHORT).show();
Looper.loop();
mainHandler.post(new Runnable() {
@Override
public void run() {
callBacks[finalI].onCatchError();
zhixing(len,finishcount,finish);
}
});
break;
case 1:
final String body = jsonObject.getString("data");
mainHandler.post(new Runnable() {
@Override
public void run() {
callBacks[finalI].onSuccess(body);
zhixing(len,finishcount,finish);
}
});
break;
case 2:
mainHandler.post(new Runnable() {
@Override
public void run() {
callBacks[finalI].onNotice();
zhixing(len,finishcount,finish);
}
});
break;
default:
break;
}
} catch (IOException e) {
Log.d(TAG, "IOException--->" + e.getMessage());
e.printStackTrace();
} catch (JSONException e) {
Log.d(TAG, "JSONException--->" + e.getMessage());
e.printStackTrace();
}
}
}
});
}
}
}