OkHttp相信都不陌生了,Android一个很好用的网络请求框架,GitHub上面2w多个Start,Square公司出品,也是JakeWharton大神的代表作之一(JakeWharton大神已离开Square公司加入Google),此处膜拜大神三秒钟……
我自己根据项目需要二次封装了OkHttp,因为和后台哥们商量的是,所有的参数全部转为Json传给服务器。上传图片时,把图片转换成Base64字符串,同样以Json的格式上传到服务器。
这是我用到的第三方依赖:
compile 'com.squareup.okhttp3:okhttp:3.8.1' //OkHttp的依赖,可能不是最新版本,可以去GitHub找最新的OkHttp依赖
compile 'id.zelory:compressor:2.0.0' //图片压缩,压缩效率和速度都不错
- 1
- 2
- 3
首先,创建一个OkHttp的单例类。在使用OkHttp时,最好保证全局只有一个OkHttpClient对象,这样方便管理和配置整个应用的网络请求的超时时间、缓存等等。如果有某个特殊的网络请求需要我们特别处理,我们也可以clone一个OkHttpClient对象单独处理。
public class OkHttpClientInstance {
public static OkHttpClient instance;
private OkHttpClientInstance() {}
public static OkHttpClient getInstance() {
if (instance == null) {
synchronized (OkHttpClientInstance.class) {
if (instance == null) {
//配置了网络请求的超时时间
instance = new OkHttpClient().newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.build();
}
}
}
return instance;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
创建网络请求类Network
public class Network {
//上下文
private Context mContext;
//请求的url
private String mUrl;
//通过单例类得到的OkHttpClient 对象
private OkHttpClient mClient;
//解析服务器返回数据的Gson
private Gson mGson;
private Handler mHandler;
//登录之后返回的Token字符串
private String mToken;
public Network(Context context, String url) {
this.mContext = context;
this.mUrl = url;
mClient = OkHttpClientInstance.getInstance();
mGson = new Gson();
mHandler = new Handler();
//获取Token的方式可以在进入程序时获取,存为全局变量
mToken = SPUtil.getString(context, SPUtil.LOGIN_TOKEN, "");
}
/**
* 执行普通的post请求,参数集合全部转为json
*
* @param map 传入的参数集合
* @param netCallBack 回调接口
*/
public void performPost(Map<Object, Object> map, final NetCallBack netCallBack) {
String params = mGson.toJson(map);
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, params);
final Request request = new Request.Builder()
.url(mUrl)
.addHeader("Authorization", "Bearer" + mToken)
.post(body)
.build();
mClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
doFailure(netCallBack);
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
doResponse(response, netCallBack);
}
});
}
/**
* post上传图片,全部转为json上传
*
* @param params 参数集合
* @param picturePathList 图片的路径集合
* @param netCallBack 回调接口
*/
public void upLoadPicture(Map<Object, Object> params, List<String> picturePathList, final NetCallBack netCallBack) {
List<PictureFileBean> fileList = new ArrayList<>();
//处理图片
for (int i = 0; i < picturePathList.size(); i++) {
File file = new File(picturePathList.get(i));
PictureFileBean fileBean = new PictureFileBean();
try {
//压缩图片
File compressedFile = new Compressor(mContext).compressToFile(file);
//把图片转为base64
String base64String = ImageToBase64.GetImageStr(compressedFile);
//拼接图片集合
fileBean.setPicFile(base64String);
fileBean.setPicType("JPEG");
fileList.add(fileBean);
} catch (IOException e) {
e.printStackTrace();
}
}
params.put("file", fileList);
String json = mGson.toJson(params);
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create(JSON, json);
final Request request = new Request.Builder()
.url(mUrl)
.addHeader("Authorization", "Bearer" + mToken)
.post(requestBody)
.build();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
doFailure(netCallBack);
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
doResponse(response, netCallBack);
}
});
}
}, 200);
}
/**
* 处理失败
*
* @param netCallBack
*/
private void doFailure(final NetCallBack netCallBack) {
mHandler.post(new Runnable() {
@Override
public void run() {
netCallBack.onNetFailure();
}
});
}
/**
* 处理成功
*
* @param response
* @param netCallBack
* @throws IOException
*/
private void doResponse(Response response, final NetCallBack netCallBack) throws IOException {
final String result = response.body().string();
if (!TextUtils.isEmpty(result)) {
try {
JSONObject jsonObject = new JSONObject(result);
String success = jsonObject.getString("success");
if ("true".equals(success)) {
mHandler.post(new Runnable() {
@Override
public void run() {
netCallBack.onSuccess(result);
}
});
} else if ("false".equals(success)) {
mHandler.post(new Runnable() {
@Override
public void run() {
netCallBack.onError(result);
}
});
}
} catch (JSONException e) {
e.printStackTrace();
mHandler.post(new Runnable() {
@Override
public void run() {
//服务器返回错误
netCallBack.onError(result);
}
});
}
}
}
/**
* 回调接口
*/
public interface NetCallBack {
//网络请求失败,没连网
void onNetFailure();
//网络请求成功
void onSuccess(String result);
//网络请求成功,后台服务器有误
void onError(String result, String errorMessage);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
我创建了一个内部接口类,用于处理网络请求结果的回调。里面有三个方法:
- onNetFailure()方法用于处理网络请求失败,没有联网的情况;
- onSuccess()方法用于处理网络请求成功的回调;
- onError()方法用于处理后台服务器返回错误的情况,通常可以结合错误码来更加规范的处理该结果 。
图片转Base64的方法
public class ImageToBase64 {
/**
* 图片转换成base64
* @param file
* @return
*/
public static String GetImageStr(File file) {
Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//参数100表示不压缩
byte[] bytes = bos.toByteArray();
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
关于调用,你可以在Activity里面直接调用Network网络层的方法,但是我不推荐你这样做。开发过程中基于高内聚、低耦合的原则,可以再写一个类,里面封装具体业务的请求方法,提供给Activity调用。
public class ActivityNet {
private Context mContext;
public AbnormalHandleActivityNet(Context context) {
mContext = context;
}
/**
* 确认处理异常点击事件
*
* @param guid
* @param abnormalCount
* @param abnormalTypePosition
* @param abnormalRemark
* @param parentGuid
* @param picturePathList
*/
public void btnConfirmHandle(String guid, String abnormalCount, int abnormalTypePosition, String abnormalRemark, String parentGuid, ArrayList<String> picturePathList, Network.NetCallBack netCallBack) {
String url = UrlUtil.getUrl("tms.app.order.backed.backExSubmit");
Map<Object, Object> params = new HashMap<>();
params.put("guid", guid);
params.put("exceptionQty", abnormalCount);
params.put("exceptionType", abnormalTypePosition);
params.put("exceptionMemo", abnormalRemark);
params.put("parentGuid", parentGuid);
Network network = new Network(mContext, url);
network.upLoadPicture(params, picturePathList, netCallBack);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
这是一个复杂的调用的方法,既需要上传参数,也需要上传图片。参数都是以键值对的方式添加进Map集合的,每个键的含义,是和后台哥们商量好的,接口文档里面都有。
picturePathList是一个图片路径的集合。我们可能会同时上传多张图片,得到多张图片的路径后,就构建成一个集合。
这个类里面是具体业务的网络请求方法,我们在Activity中直接调用这个类里面的方法。Activity可以通过实现Network.NetCallBack接口来处理结果并作出相应的UI更新。