对Okhttp3进行二次封装,对外提供了POST请求、GET请求、PATCH请求、PUT请求、DELETE请求、上传文件、下载文件、取消请求、Raw/Json/Gson返回、后台下载管理等功能.
对于Okhttp3的封装参考了:
- https://github.com/hongyangAndroid/okhttputils
- https://github.com/jeasonlzy/okhttp-OkGo
- https://github.com/ZhaoKaiQiang/OkHttpPlus
cookie本地持久化使用了PersistentCookieJar:
compile 'com.tsy:myokhttp:1.1.4'在项目入口创建唯一MyOkhttp实例
MyOkHttpmMyOkhttp = newMyOkHttp();也可以自行配置OkhttpClient.
OkHttpClientokHttpClient = newOkHttpClient.Builder()
.connectTimeout(10000L, TimeUnit.MILLISECONDS)
.readTimeout(10000L, TimeUnit.MILLISECONDS)
//其他配置
.build();
MyOkHttpmMyOkhttp = newMyOkHttp(okHttpClient);设置cookie.
//设置开启cookieClearableCookieJarcookieJar =
newPersistentCookieJar(newSetCookieCache(), newSharedPrefsCookiePersistor(getApplicationContext()));
OkHttpClientokHttpClient = newOkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
mMyOkHttp = newMyOkHttp(okHttpClient);整个调用采用链式调用的方式. 方便以后扩展.
现在有Get, Post, Patch, Put, Delete, Upload, Download 这些请求方式
添加参数可以使用addParam一个个添加, 也可以使用params一次性添加
添加参数可以使用addHeader一个个添加, 也可以使用headers一次性添加
现在回调格式有以下几种:
- Raw原生数据 RawResponseHandler
- Json JsonResponseHandler
- Gson GsonResponseHandler
kv参数
Stringurl = "http://192.168.2.135/myokhttp/post.php";
Map<String, String> params = newHashMap<>();
params.put("name", "tsy");
params.put("age", "24");
mMyOkhttp.post()
.url(url)
.params(params)
.tag(this)
.enqueue(newJsonResponseHandler() {
@OverridepublicvoidonSuccess(intstatusCode, JSONObjectresponse) {
Log.d(TAG, "doPost onSuccess JSONObject:" + response);
}
@OverridepublicvoidonSuccess(intstatusCode, JSONArrayresponse) {
Log.d(TAG, "doPost onSuccess JSONArray:" + response);
}
@OverridepublicvoidonFailure(intstatusCode, Stringerror_msg) {
Log.d(TAG, "doPost onFailure:" + error_msg);
}
});json参数
Stringurl = "http://192.168.2.135/myokhttp/post_json.php";
JSONObjectjsonObject = newJSONObject();
try {
jsonObject.put("name", "tsy");
jsonObject.put("age", 24);
jsonObject.put("type", "json");
} catch (JSONExceptione) {
e.printStackTrace();
}
mMyOkhttp.post()
.url(url)
.jsonParams(jsonObject.toString()) //与params不共存 以jsonParams优先
.tag(this)
.enqueue(newJsonResponseHandler() {
@OverridepublicvoidonSuccess(intstatusCode, JSONObjectresponse) {
Log.d(TAG, "doPostJSON onSuccess JSONObject:" + response);
}
@OverridepublicvoidonSuccess(intstatusCode, JSONArrayresponse) {
Log.d(TAG, "doPostJSON onSuccess JSONArray:" + response);
}
@OverridepublicvoidonFailure(intstatusCode, Stringerror_msg) {
Log.d(TAG, "doPostJSON onFailure:" + error_msg);
}
});Stringurl = "http://192.168.2.135/myokhttp/get.php";
mMyOkhttp.get()
.url(url)
.addParam("name", "tsy")
.addParam("id", "5")
.tag(this)
.enqueue(newRawResponseHandler() {
@OverridepublicvoidonSuccess(intstatusCode, Stringresponse) {
Log.d(TAG, "doGet onSuccess:" + response);
}
@OverridepublicvoidonFailure(intstatusCode, Stringerror_msg) {
Log.d(TAG, "doGet onFailure:" + error_msg);
}
});Stringurl = "http://192.168.2.135/myokhttp/patch.php/id/5/name/tsy";
mMyOkhttp.patch()
.url(url)
.tag(this)
.enqueue(newJsonResponseHandler() {
@OverridepublicvoidonSuccess(intstatusCode, JSONObjectresponse) {
Log.d(TAG, "doPatch onSuccess:" + response);
}
@OverridepublicvoidonFailure(intstatusCode, Stringerror_msg) {
Log.d(TAG, "doPatch onFailure:" + error_msg);
}
});Stringurl = "http://192.168.2.135/myokhttp/put.php/id/5/name/tsy/age/15";
mMyOkhttp.put()
.url(url)
.tag(this)
.enqueue(newJsonResponseHandler() {
@OverridepublicvoidonSuccess(intstatusCode, JSONObjectresponse) {
Log.d(TAG, "doPut onSuccess:" + response);
}
@OverridepublicvoidonFailure(intstatusCode, Stringerror_msg) {
Log.d(TAG, "doPut onFailure:" + error_msg);
}
});Stringurl = "http://192.168.2.135/myokhttp/delete.php/id/5";
mMyOkhttp.delete()
.url(url)
.tag(this)
.enqueue(newJsonResponseHandler() {
@OverridepublicvoidonSuccess(intstatusCode, JSONObjectresponse) {
Log.d(TAG, "doDelete onSuccess:" + response);
}
@OverridepublicvoidonFailure(intstatusCode, Stringerror_msg) {
Log.d(TAG, "doDelete onFailure:" + error_msg);
}
});Stringurl = "http://192.168.2.135/myokhttp/upload.php";
mMyOkhttp.upload()
.url(url)
.addParam("name", "tsy")
.addFile("avatar",
newFile(Environment.getExternalStorageDirectory()
+ "/ahome/sasas.jpg")) //上传已经存在的File// .addFile("avatar2", "asdsda.png", byteContents) //直接上传File bytes
.tag(this)
.enqueue(newGsonResponseHandler<UploadModel>() {
@OverridepublicvoidonFailure(intstatusCode, Stringerror_msg) {
Log.d(TAG, "doUpload onFailure:" + error_msg);
}
@OverridepublicvoidonProgress(longcurrentBytes, longtotalBytes) {
Log.d(TAG, "doUpload onProgress:" + currentBytes + "/" + totalBytes);
}
@OverridepublicvoidonSuccess(intstatusCode, UploadModelresponse) {
Log.d(TAG, "doUpload onSuccess:" + response.ret + " " + response.msg);
}
});Stringurl = "http://192.168.2.135/myokhttp/head.jpg";
mMyOkhttp.download()
.url(url)
.filePath(Environment.getExternalStorageDirectory() + "/ahome/a.jpg")
.tag(this)
.enqueue(newDownloadResponseHandler() {
@OverridepublicvoidonStart(longtotalBytes) {
Log.d(TAG, "doDownload onStart");
}
@OverridepublicvoidonFinish(FiledownloadFile) {
Log.d(TAG, "doDownload onFinish:");
}
@OverridepublicvoidonProgress(longcurrentBytes, longtotalBytes) {
Log.d(TAG, "doDownload onProgress:" + currentBytes + "/" + totalBytes);
}
@OverridepublicvoidonFailure(Stringerror_msg) {
Log.d(TAG, "doDownload onFailure:" + error_msg);
}
});mMyOkhttp.cancel(this); //tag 即之前请求时传入的tag 建议直接将页面作为object传入实现了下载管理的核心逻辑,包括添加下载任务、开始任务、暂停任务、删除任务、任务下载等待、下载进度和状态监听等功能。依赖于MyOkhttp
项目中创建DownloadMgr继承AbstractDownloadMgr,并实现下载任务的状态,进度的本地持久化保存。(AbstractDownloadMgr只负责在内存中存储所有任务, 需要项目自行实现本地持续化存储,重新进入App后的任务恢复等)
示例:
/** * 实现下载管理 AbstractDownloadMgr * Created by tsy on 2016/11/24. */publicclassDownloadMgrextendsAbstractDownloadMgr {
privateDownloadMgr(Builderbuilder) {
super(builder);
}
/** * 初始进入app 恢复所有未完成的任务 */@OverridepublicvoidresumeTasks() {
if(DEBUG) {
Log.i(TAG, "start resumeTasks");
}
//获取所有未完成的任务(已完成的不需要添加)DownloadContract.InteractordownloadInteractor = newDownloadInteractor();
ArrayList<Task> tasks = downloadInteractor.parseTask(downloadInteractor.getAllUnfinishedDownloadTasks());
//将任务加到下载管理队列中if(tasks != null && tasks.size() > 0) {
for(inti = 0; i < tasks.size(); i ++) {
Tasktask = tasks.get(i);
task.setDefaultStatus(DEFAULT_TASK_STATUS_PAUSE); //所有任务初始设置为暂停addTask(tasks.get(i));
}
downloadInteractor.pauseAllTask();
}
}
/** * 保存进度 * @param taskId taskId * @param currentBytes 已经下载的bytes * @param totalBytes 总共bytes */@OverrideprotectedvoidsaveProgress(StringtaskId, longcurrentBytes, longtotalBytes) {
DownloadContract.InteractordownloadInteractor = newDownloadInteractor();
downloadInteractor.updateProgress(taskId, currentBytes, totalBytes);
}
/** * 下载任务开始 * @param taskId task id */@OverrideprotectedvoidonTaskStart(StringtaskId) {
DownloadContract.InteractordownloadInteractor = newDownloadInteractor();
downloadInteractor.startTask(taskId);
}
/** * 下载任务暂停 * @param taskId task id */@OverrideprotectedvoidonTaskPause(StringtaskId) {
DownloadContract.InteractordownloadInteractor = newDownloadInteractor();
downloadInteractor.pauseTask(taskId);
}
/** * 下载任务完成 * @param taskId task id */@OverrideprotectedvoidonTaskFinish(StringtaskId) {
DownloadContract.InteractordownloadInteractor = newDownloadInteractor();
downloadInteractor.finishTask(taskId);
}
/** * 下载任务失败 * @param taskId task id */@OverrideprotectedvoidonTaskFail(StringtaskId) {
//失败设置为暂停 允许用户再次尝试开始DownloadContract.InteractordownloadInteractor = newDownloadInteractor();
downloadInteractor.pauseTask(taskId);
}
//实现BuilderpublicstaticclassBuilderextendsAbstractDownloadMgr.Builder {
@OverridepublicAbstractDownloadMgrbuild() {
returnnewDownloadMgr(this);
}
}
}mDownloadMgr = (DownloadMgr) newDownloadMgr.Builder()
.myOkHttp(mMyOkhttp)
.maxDownloadIngNum(5) //设置最大同时下载数量(不设置默认5)
.saveProgressBytes(50 * 1024) //设置每50kb触发一次saveProgress保存进度 (不能在onProgress每次都保存 过于频繁) 不设置默认50kb
.build();mDownloadMgr.resumeTasks();DownloadMgr.Tasktask = newDownloadMgr.Task();
task.setTaskId(mDownloadMgr.genTaskId()); //生成一个taskIdtask.setUrl("xxxxx"); //下载地址task.setFilePath("xxxxxxx"); //下载后文件保存位置task.setCompleteBytes(1234L); //设置已完成的bytes (用于恢复任务时添加,如果新添加的任务不需要设置该字段)task.setDefaultStatus(DownloadMgr.DEFAULT_TASK_STATUS_START); //任务添加后开始状态 如果不设置 默认任务添加后就自动开始mDownloadMgr.addTask(task);mDownloadMgr.startTask("taskId");
mDownloadMgr.pauseTask("taskId");PS:不要使用匿名类,会造成内存泄露。在onStart或者onResume时初始化监听,在onStop或者onPause时销毁监听
@OverridepublicvoidonResume() {
super.onResume();
//每次显示页面的时候加上监听mDownloadTaskListener = newDownloadTaskListener() {
@OverridepublicvoidonStart(StringtaskId, longcompleteBytes, longtotalBytes) {
//开始下载
}
@OverridepublicvoidonProgress(StringtaskId, longcurrentBytes, longtotalBytes) {
//下载进度//建议使用handler延迟刷新下载进度 不然过于频繁刷新if(!mMyHandler.hasMessages(MSG_DELAY_NOTIFICAION)) {
Messagemessage = newMessage();
message.what = MSG_DELAY_NOTIFICAION;
mMyHandler.sendMessageDelayed(message, 300);
}
}
@OverridepublicvoidonPause(StringtaskId, longcurrentBytes, longtotalBytes) {
//下载暂停
}
@OverridepublicvoidonFinish(StringtaskId, Filefile) {
//下载完成
}
@OverridepublicvoidonFailure(StringtaskId, Stringerror_msg) {
//下载失败
}
};
//加入监听mDownloadMgr.addListener(mDownloadTaskListener);
}
@OverridepublicvoidonPause() {
//释放监听 防止内存泄露mDownloadMgr.removeListener(mDownloadTaskListener);
mDownloadTaskListener = null;
super.onPause();
}/** * 初始进入app 恢复所有未完成的任务 */voidresumeTasks()/** * 添加下载任务 * @param task Task */DownloadTaskaddTask(Tasktask)/** * 开始任务 * @param taskId task id */voidstartTask(StringtaskId)/** * 开始所有任务 */voidstartAllTask()/** * 暂停任务 * @param taskId task id */voidpauseTask(StringtaskId)/** * 暂停所有任务 */voidpauseAllTask()/** * 删除任务 * @param taskId 任务id */voiddeleteTask(StringtaskId)/** * 添加下载监听 * @param downloadTaskListener */voidaddListener(DownloadTaskListenerdownloadTaskListener)/** * 移除下载监听 * @param downloadTaskListener */voidremoveListener(DownloadTaskListenerdownloadTaskListener)/** * 生成taskId yyyyMMddHHmmss+3位随机数字 * @return */StringgenTaskId()/** * 获取当前任务的下载任务信息 * @param taskId 任务id * @return */DownloadTaskgetDownloadTask(StringtaskId)publicclassDownloadStatus {
publicstaticfinalintSTATUS_DEFAULT = -1; //初始状态publicstaticfinalintSTATUS_WAIT = 0; //队列等待中publicstaticfinalintSTATUS_PAUSE = 1; //暂停publicstaticfinalintSTATUS_DOWNLOADING = 2; //下载中publicstaticfinalintSTATUS_FINISH = 3; //下载完成publicstaticfinalintSTATUS_FAIL = 4; //下载失败
}publicinterfaceDownloadTaskListener {
/** * 任务开始 * @param taskId task id * @param completeBytes 断点续传 已经完成的bytes * @param totalBytes total bytes */voidonStart(StringtaskId, longcompleteBytes, longtotalBytes);
/** * 任务下载中 * @param taskId task id * @param currentBytes 当前已经下载的bytes * @param totalBytes total bytes */voidonProgress(StringtaskId, longcurrentBytes, longtotalBytes);
/** * 任务暂停 * @param taskId task id * @param currentBytes 当前已经下载的bytes * @param totalBytes total bytes */voidonPause(StringtaskId, longcurrentBytes, longtotalBytes);
/** * 任务完成 * @param taskId task id * @param file 下载完成后的file */voidonFinish(StringtaskId, Filefile);
/** * 任务失败 * @param taskId task id * @param error_msg error_msg */voidonFailure(StringtaskId, Stringerror_msg);
}#myokhttp
-dontwarn com.tsy.sdk.myokhttp.**
-keep class com.tsy.sdk.myokhttp.**{*;}
#okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
#okio
-dontwarn okio.**
-keep class okio.**{*;}
#persistentcookiejar
-dontwarn com.franmontiel.persistentcookiejar.**
-keep class com.franmontiel.persistentcookiejar.**{*;}
#gson
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
## 还有所有定义的实体类
简书地址:http://www.jianshu.com/users/21716b19302d/latest_articles
微信公众号
Copyright 2017 SY.Tang
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.