okgo网络请求框架的实现
第一步:添加依赖:
implementation 'com.lzy.net:okgo:3.0.4' implementation 'com.lzy.net:okrx2:2.0.2' implementation 'com.lzy.net:okserver:2.0.5'
第二步: 创建HttpManager:示例:
import android.content.Context; import com.lzy.okgo.OkGo; import com.shiwen.oil.bean.result.DailyDataResult; import com.shiwen.oil.constant.HttpUrlConstants; import com.shiwen.oil.util.JsonParseUtil; import org.json.JSONObject; /** * 网络请求管理类 */ public class HttpManager { private volatile static HttpManager instance; private HttpManager(Context mContext) { } public static HttpManager getInstance(Context mContext) { if (instance == null) { synchronized (HttpManager.class) { if (instance == null) { instance = new HttpManager(mContext); } } } return instance; } public void getDialyData( String ksrq, HttpStringResponseHandler<DailyDataResult> handler) { OkGo.<String>post(HttpUrlConstants.HTTP_URL + HttpUrlConstants.DAILY_DATA_URL) .params("ksrq",ksrq) .execute(handler); } public void getLoanOrderLists(GetLoanOrderParams postParams, Context context, HttpStringResponseHandler<GetLoanOrderListsResult> handler) { JSONObject jsonRequest = JsonParseUtil.beanParseJson(HttpUrlConstants.GETLOANORDERLIST, postParams, context); OkGo.<String>post(HttpUrlConstants.HTTP_URL + HttpUrlConstants.GETLOANORDERLIST) .upJson(jsonRequest) .execute(handler); }
public void loanImg(File file, Context context, HttpStringResponseHandler<LoanImgResult> handler) { FileUtils.compressImageToFile(file); OkGo.<String>post(HttpUrlConstants.HTTP_URL + HttpUrlConstants.LOANIMG) .params("userid", ConfigConstants.getUid(context)) .params("image", file) .execute(handler); }
}
第三步:创建JsonParseUtil:
import android.content.Context; import com.google.gson.Gson; import com.google.gson.JsonParseException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class JsonParseUtil { private static ObjectMapper objectMapper = new ObjectMapper(); public JsonParseUtil() { } public static JSONObject beanParseJson(String method, Object request, Context mContext) { Gson gson = new Gson(); JSONObject json = null; try { if (request != null) { json = new JSONObject(gson.toJson(request)); } else { json = new JSONObject(); } // json.put("userid", ConfigConstants.getToken(mContext)); } catch (JSONException e) { e.printStackTrace(); } return json; } public static Object jsonParseResponse(JSONObject json, Class... responses) { Object obj = null; if (responses.length > 1) { try { obj = responses[0].newInstance(); Field[] var6; int var5 = (var6 = responses[0].getDeclaredFields()).length; for (int var4 = 0; var4 < var5; ++var4) { Field e = var6[var4]; if (!e.getType().isAssignableFrom(ArrayList.class)) { Method var20 = responses[0].getMethod(ReflectUtil.setterNameFromField(e), new Class[]{e.getType()}); var20.invoke(obj, new Object[]{json.get(e.getName())}); } else { JSONArray m = json.getJSONArray(e.getName()); Object[] objects = (Object[]) Array.newInstance(responses[1], m.length()); for (int list = 0; list < objects.length; ++list) { objects[list] = jsonParseResponse(m.getJSONObject(list), (Class[]) Arrays.copyOfRange(responses, 1, responses.length)); } List var21 = asList(objects); Method m1 = responses[0].getMethod(ReflectUtil.setterNameFromField(e), new Class[]{var21.getClass()}); m1.invoke(obj, new Object[]{var21}); } } } catch (InstantiationException var14) { var14.printStackTrace(); } catch (IllegalAccessException var15) { var15.printStackTrace(); } catch (JSONException var16) { var16.printStackTrace(); } catch (NoSuchMethodException var17) { var17.printStackTrace(); } catch (IllegalArgumentException var18) { var18.printStackTrace(); } catch (InvocationTargetException var19) { var19.printStackTrace(); } } else { try { obj = objectMapper.readValue(json.toString(), responses[0]); } catch (JsonParseException var11) { var11.printStackTrace(); } catch (JsonMappingException var12) { var12.printStackTrace(); } catch (IOException var13) { var13.printStackTrace(); } } return obj; } public static <T> List<T> asList(T... a) { ArrayList list = new ArrayList(); Collections.addAll(list, a); return list; } }
第四步创建:HttpStringResponseHandler
import android.content.Context; import com.google.gson.Gson; import com.lzy.okgo.callback.StringCallback; import com.lzy.okgo.model.Response; import com.lzy.okgo.request.base.Request; import com.shiwen.oil.util.GsonUtil; import com.shiwen.oil.util.LoggerUtil; import com.shiwen.oil.widget.ProgressDialog; /** * 网络请求返回处理类 */ public abstract class HttpStringResponseHandler<T> extends StringCallback { private static final String TAG = "HttpStringResponseHandler"; private Context context; private Class<T> cls; private boolean isNeedParse; private boolean isNeedProgress; /** * 不需要解析时使用 * * @param context * @param isNeedProgress */ public HttpStringResponseHandler(Context context, boolean isNeedProgress) { this.context = context; this.isNeedProgress = isNeedProgress; } /** * 需要解析时,使用 * * @param context * @param cls * @param isNeedParse * @param isNeedProgress */ public HttpStringResponseHandler(Context context, Class<T> cls, boolean isNeedParse, boolean isNeedProgress) { this.context = context; this.cls = cls; this.isNeedParse = isNeedParse; this.isNeedProgress = isNeedProgress; } @Override public void onStart(Request<String, ? extends Request> request) { if (isNeedProgress && context != null) ProgressDialog.getInstance().startProgressDialog(context, "加载中"); } @Override public void onFinish() { if (isNeedProgress) ProgressDialog.getInstance().stopProgressDialog(); } @Override public void onError(Response<String> response) { LoggerUtil.e("网络访问异常,请检查网络!" + response.toString()); onFaile("网络访问异常,请检查网络!"); if (isNeedProgress) ProgressDialog.getInstance().stopProgressDialog(); } @Override public void onSuccess(/*String response, int id*/Response<String> response) { LoggerUtil.e("onResponse = " + response.body()); if (isNeedProgress) ProgressDialog.getInstance().stopProgressDialog(); if (isNeedParse) { try { Gson gson = GsonUtil.getInstance(); T result = gson.fromJson(response.body().trim(), cls); onSuccess(result); } catch (Exception e) { onFaile("数据错误!"); LoggerUtil.e("onSuccess Exception : " + e.toString() + " "); e.printStackTrace(); } } else { onSuccessWithNoparse(response.body()); } } /** * 需要解析时的回调 * * @param t */ public void onSuccess(T t) { LoggerUtil.systemOut(t.toString()); } /** * 不需要解析时的回调 * * @param result */ public void onSuccessWithNoparse(String result) { } /** * 失败的回调 * * @param res */ public void onFaile(String res) { LoggerUtil.systemOut("http onFaile ---> "+res); } }
第五步,代码中使用:
private void getDailyDatefromNet() { refreshLayout.setRefreshing(true); String ksrq = tvDate.getText().toString().trim(); HttpManager.getInstance(getActivity()).getDialyData(ksrq, new HttpStringResponseHandler<DailyDataResult>(getActivity(), DailyDataResult.class, true, false) { @Override public void onSuccess(DailyDataResult dailyDataResult) { super.onSuccess(dailyDataResult); } @Override public void onFaile(String res) { super.onFaile(res); } @Override public void onError(Response<String> response) { super.onError(response); } }); }
示例2:图片上传:
HttpManager.getInstance(DataActivity.this).loanImg(new File(cropImagePath), LoanDataStep1Activity.this, new HttpStringResponseHandler<LoanImgResult>(LoanDataStep1Activity.this, LoanImgResult.class, true, true) { @Override public void onSuccess(final LoanImgResult response) { super.onSuccess(response); } });
文件下载OkDownload
OkGo与OkDownload的区别就是,OkGo只是简单的做一个下载功能,不具备断点下载,暂停等操作,但是这在很多时候已经能满足需要了。
而有些app需要有一个下载列表的功能,就像迅雷下载一样,每个下载任务可以暂停,可以继续,可以重新下载,可以有下载优先级,这时候OkDownload就有用了。
- 结合OkGo的request进行网络请求,支持与OkGo保持相同的配置方法和传参方式
- 支持断点下载,支持突然断网,强杀进程后,继续断点下载
- 每个下载任务具有无状态、下载、暂停、等待、出错、完成共六种状态
- 所有下载任务按照tag区分,切记不同的任务必须使用不一样的tag,否者断点会发生错乱
- 相同的下载url地址,如果使用不一样的tag,也会认为是两个下载任务
- 不同的下载url地址,如果使用相同的tag,会认为是同一个任务,导致断点错乱
- 默认同时下载数量为3个,默认下载路径
/storage/emulated/0/download
,下载路径和下载数量都可以在代码中配置 - 下载文件名可以自己定义,也可以不传,让框架自动获取文件名
简单实现代码:
HttpManager.getInstance(this).downloadFile(new DownloadListener("tasgTag") { @Override public void onStart(Progress progress) { LoggerUtil.systemOut(progress+"progress"); } @Override public void onProgress(Progress progress) { LoggerUtil.systemOut(progress+"progress"); } @Override public void onError(Progress progress) { LoggerUtil.systemOut(progress+"progress"); } @Override public void onFinish(File file, Progress progress) { LoggerUtil.systemOut(progress+"progress"); } @Override public void onRemove(Progress progress) { LoggerUtil.systemOut(progress+"progress"); } });
/** * 下载 * * @param */ public void downloadFile(DownloadListener downloadListener) { Request<File, ? extends Request> request = OkGo.<File>get("http://192.168.0.195:8088/test.apk"); OkDownload.getInstance().request("tasgTag", request) .fileName("test.apk") .folder(CommonConstants.appDir.getPath()) .save() .register(downloadListener) .start(); }
- 构建一个下载请求Request,这个构建方法和OkGo是一样的,params参数和headers参数是只是演示使用,一切OkGo的使用方法,这里都是一样的。
- 构建下载任务,使用OkDownload中的request方法,传入一个tag和我们上一步创建的request对象,创建出下载任务,其他的方法我们下文在细讲。
- 启动任务,我们已经得到了DownloadTask任务对象,那么简单调用start启动他就好了,同时他还支持这么几个方法:
- start():开始一个新任务,或者继续下载暂停的任务都是这个方法
- pause():将一个下载中的任务暂停
- remove():移除一个任务,无论这个任务是在下载中、暂停、完成还是其他任何状态,都可以直接移除这个任务,他有一个重载方法,接受一个boolen参数,true表示删除任务的时候同时删除文件,false表示只删除任务,但是文件保留在手机上。不传的话,默认为false,即不删除文件。
- restart():重新下载一个任务。重新下载会先删除以前的任务,同时也会删除文件,然后从头开始重新下载该文件。
Request的构建详细参考OkGo的用法,这里重点介绍DownloadTask的构建,这里面的方法一个个介绍:
- request():静态方法创建DownloadTask对象,接受两个参数,第一个参数是tag,表示当前任务的唯一标识,就像介绍中说的,所有下载任务按照tag区分,不同的任务必须使用不一样的tag,否者断点会发生错乱,如果相同的下载url地址,如果使用不一样的tag,也会认为是两个下载任务,不同的下载url地址,如果使用相同的tag,也会认为是同一个任务,导致断点错乱。切记,切记!!
- priority():表示当前任务的下载优先级,他是一个int类型的值,只要在int的大小范围内,数值越大,优先级越高,也就会优先下载。当然也可以不设置,默认优先级为0,当所有任务优先级都一样的时候,就会按添加顺序下载。
- floder():单独指定当前下载任务的文件夹目录,如果你是6.0以上的系统,记得下载的时候先自己获取sd卡的运行时权限,否则文件夹创建不成功,无法下载。当然也可以不指定,默认下载路径
/storage/emulated/0/download
。 - fileName():手动指定下载的文件名,一般来说是不需要手动指定的,也建议不要自己指定,除非你明确知道你要下载的是什么,或者你想改成你自己的文件名。如果不指定,文件名将按照以下规则自动获取,获取规则与OkGo文件下载获取规则一致,点击这里查看。
- extra():这个方法相当于数据库的扩展字段,我们知道我们断点下载是需要保存下载进度信息的,而我们这个框架是保存在数据库中,数据库的字段都是写死的,如果用户想在我们的下载数据库中保存自己的数据就做不到了,所以我们这里提供了三个扩展字段,允许用户保存自己想要的数据,如果不需要的话,也不用调用该方法。
- register():这是个注册监听的方法,我们既然要下载文件,那么我们肯定要知道下载的进度和状态是吧,就在这里注册我们需要的监听,监听可以注册多个,同时生效,当状态发生改变的时候,每个监听都会收到通知。当然如果你只是想下载一个文件,不关心他的回调,那么你不用注册任何回调。
最后,关注【码上加油站】微信公众号后,有疑惑有问题想加油的小伙伴可以码上加入社群,让我们一起码上加油吧!!!
posted on 2018-10-12 15:20 LoaderMan 阅读(5183) 评论(0) 编辑 收藏 举报