//OkHttp请求封装工具类
public class OkHttpManager {
private OkHttpClient okHttpClient;
private Handler mHandler;
private volatile static OkHttpManager manager;//防止多个线程访问该工具类,发生并发修改异常
private OkHttpManager() {
okHttpClient = new OkHttpClient();
mHandler = new Handler(Looper.getMainLooper());
}
/**
* 获取OkHttpManager单一实例
* 注:
* 1.synchronized关键字用于多线程访问程序中的共享资源时实现顺序同步访问资源
* 2.synchronized关键字修饰代码块---同步代码块;
* 同一时间段,只能被同一线程调用,其他线程只能等待。【防止并发修改异常】
*/
public static OkHttpManager getInstance() {
OkHttpManager instance = null;
if (manager == null) {
synchronized (OkHttpManager.class) {
if (instance == null) {
instance = new OkHttpManager();
manager = instance;
}
}
}
return instance;
}
/**
* 异步Get请求
*
* @param url
* @param callBackJsonResult
*/
public void sendGet(String url, final CallBackJsonResult callBackJsonResult) {
final Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(new Callback() {//注:同步请求:execute();异步请求:enqueue(new Callback())
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();//打印异常
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSuccessJsonStringMethod(response.body().string(), callBackJsonResult);
}
}
});
}
/**
* 模拟表单Post提交
*
* @param url 地址
* @param params 请求参数
* @param callBack 请求成功回调
*/
public void sendPost(String url, Map<String, String> params, final CallBackJSONObjectResult callBack) {
//创建Form表单对象,add多个键值队
FormBody.Builder formBodyBuilder = new FormBody.Builder();
if (params != null && !params.isEmpty()) {
for (Map.Entry<String, String> entry : params.entrySet()) {
formBodyBuilder.add(entry.getKey(), entry.getValue());
}
}
RequestBody requestBody = formBodyBuilder.build();//From表单对象
//创建一个Request请求,发起异步网络请求
Request request = new Request.Builder().url(url).post(requestBody).build();//post请求
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSuccessJsonObjectMethod(response.body().string(), callBack);
}
}
});
}
/**
* post请求上传文件和参数
* @param url
* @param map
* @param fileList
* @param callBack
*/
public void postFileAndParams(final String url, final Map<String, Object> map, List<File> fileList,final CallBackJSONObjectResult callBack) {
//1.form表单形式上传(分块上传)
MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
multipartBodyBuilder.setType(MultipartBody.FORM);//设置为表单类型
for (File file : fileList) {//文件
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);//添加多个文件
multipartBodyBuilder.addFormDataPart("files", file.getName(), fileBody);//files-文件对应的键名
}
if (map != null) {//普通参数[添加表单键值]
for (Map.Entry entry : map.entrySet()) {
multipartBodyBuilder.addFormDataPart(valueOf(entry.getKey()), valueOf(entry.getValue()));
}
}
RequestBody requestBody = multipartBodyBuilder.build();//分块请求对象
//2.创建一个Request请求,发起异步网络请求,readTimeout("请求超时时间" , 时间单位);
Request request = new Request.Builder().url(url).post(requestBody).build();
okHttpClient.newBuilder().readTimeout(6000, TimeUnit.MILLISECONDS).build().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSuccessJsonObjectMethod(response.body().string(), callBack);
}
}
});
}
/**
* 小文件下载
* @param url 下载连接
* @param saveDir 储存下载文件的SDCard目录
* @param name 文件名
* @param listener 下载监听
*/
public void download(final String url, final String saveDir, final String name, final OnDownloadListener listener) {
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 下载失败
listener.onDownloadFailed();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
// 储存下载文件的目录
String savePath = isExistDir(saveDir);
try {
is = response.body().byteStream();
long total = response.body().contentLength();
File file = new File(savePath, name);
fos = new FileOutputStream(file);
long sum = 0;
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
sum += len;
int progress = (int) (sum * 1.0f / total * 100);
// 下载中
listener.onDownloading(progress);
}
fos.flush();
// 下载完成
listener.onDownloadSuccess();
} catch (Exception e) {
listener.onDownloadFailed();
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
try {
if (fos != null)
fos.close();
} catch (IOException e) {
}
}
}
});
}
/**
* @param saveDir
* @return
* @throws IOException 判断下载目录是否存在
*/
private String isExistDir(String saveDir) throws IOException {
// 下载位置
File downloadFile = new File(saveDir);
if (!downloadFile.mkdirs()) {
downloadFile.createNewFile();
}
String savePath = downloadFile.getAbsolutePath();
return savePath;
}
/**
* @param url
* @return 从下载连接中解析出文件名
*/
@NonNull
private String getNameFromUrl(String url) {
return url.substring(url.lastIndexOf("/") + 1);
}
public interface OnDownloadListener {
/**
* 下载成功
*/
void onDownloadSuccess();
/**
* @param progress 下载进度
*/
void onDownloading(int progress);
/**
* 下载失败
*/
void onDownloadFailed();
}
/**
* 请求返回的结果是json字符串
*
* @param jsonValue
* @param callBack
*/
private void onSuccessJsonStringMethod(final String jsonValue, final CallBackJsonResult callBack) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
try {
callBack.onResponse(jsonValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
/**
* 请求返回的是byte[] 数组
*
* @param data
* @param callBack
*/
private void onSuccessByteMethod(final byte[] data, final CallBackByteResult callBack) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
callBack.onResponse(data);
}
}
});
}
/**
* 返回响应的结果是json对象
*
* @param jsonValue
* @param callBack
*/
private void onSuccessJsonObjectMethod(final String jsonValue, final CallBackJSONObjectResult callBack) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
try {
callBack.onResponse(new JSONObject(jsonValue));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
/**
* 请求返回的结果是json字符串-回调接口
*/
public interface CallBackJsonResult {
void onResponse(String result);
}
/**
* 请求返回的结果是JSONObject对象-回调接口
*/
public interface CallBackJSONObjectResult {
void onResponse(JSONObject jsonObject);
}
/**
* 请求返回的结果是byte[]字节数组-回调接口
*/
public interface CallBackByteResult {
void onResponse(byte[] result);
}
//=====================1.MediaType详解=====================
/*
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
属性:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
以application开头的媒体格式类型:
application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
注意:MediaType.parse("image/png")里的"image/png"不知道该填什么,可以参考---》http://www.w3school.com.cn/media/media_mimeref.asp
如何使用呢?(在请求体里面写入类型和需要写入的数据,通过post请求)
String body = "hdsoifhjoihdsfh";
RequestBody body = RequestBody.create(MEDIA_TYPE_MARKDOWN, body);
*/
//=====================2.超时设置=====================
/*OkHttpClient client=new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS) //设置连接超时
.readTimeout(60, TimeUnit.SECONDS) //设置读超时
.writeTimeout(60,TimeUnit.SECONDS) //设置写超时
.retryOnConnectionFailure(true) //是否自动重连
.build();*/
}
网友评论