oKHttp基本封装
来源:互联网 发布:cmd获取软件版本号 编辑:程序博客网 时间:2024/06/08 02:47
需求:
- get请求和post请求,上传文件和下载文件时返回进度
- oKHttpClient实例只创建一次
- 如果用户在结果还未返回时又连续多次请求相同的api,只保留最后一次,前面的中断请求
- 返回的JSON数据转化成实体对象
- 访问服务器是异步请求,将请求结果回调到主线程
首先用一个抽象类用于回调
public abstract class ResultCallback { public abstract void onError(Request request,Exception e); public abstract void onSuccess(Object str);}
oKHttp无论哪种方式请求都是创建OkHttpClient、Request和Call对象,然后在调用Call的enqueue()方法。
private volatile static oKHttpEngine mInstance; private oKHttpEngine(){} public static oKHttpEngine getInstance(){ if(mInstance == null){ synchronized (oKHttpEngine.class){ if(mInstance == null){ mInstance = new oKHttpEngine(); } } } return mInstance; }
使用单例设计模式,获取类的对象,由于是单例设计模式,所以无论对getInstance()调用多少次都只会创建一个对象
public void setHttpConfig(HttpConfig httpConfig){ this.httpConfig = httpConfig; client = new OkHttpClient.Builder() .connectTimeout(httpConfig.getConnectionTimeOut(), TimeUnit.SECONDS) .readTimeout(httpConfig.getReadTmeOut(),TimeUnit.SECONDS) .writeTimeout(httpConfig.getWriteTimeOut(),TimeUnit.SECONDS) .proxy(Proxy.NO_PROXY) .build(); mHandler = new Handler(); gson = new Gson();}
创建oKHttpClient对象,并设置链接时间,读取时间等信息,此方法必须被调用。并创建Gson对象和Handler对象。
private Call execute(Request.Builder builder,Header[] h, ResultCallback resultCallback,String url){ //设置请求头信息 boolean hasUa = false; if(h==null){ builder.header("Connection","close"); builder.header("Accept","*/*"); }else { for (Util.Header header:h){ builder.header(header.getName(),header.getValue()); if(!hasUa&&header.getName().equals("User-Agent")){ hasUa = true; } } } if(!hasUa&&!TextUtils.isEmpty(httpConfig.getUserAgent())){ builder.header("User-Agent",httpConfig.getUserAgent()); } Call call = client.newCall(builder.build()); dealResult(call,resultCallback,url); return call; }
首先设置请求头信息,通常不需要设置,通过build()方法创建Request对象,并且创建Call对象
private void dealResult(Call call, final ResultCallback resultCallback, final String url){ call.enqueue(new Callback() { @Override public void onFailure(Call call,IOException e) { sendFailed(call.request(),resultCallback,e); } @Override public void onResponse(Call call, final Response response) throws IOException { if(resultCallback!=null){ try { String str = response.body().string(); if(clazz!=null||clazzBean!=null){ JSONObject jsonObject = new JSONObject(str); String strData = jsonObject.toString(); //用于解析JSON中的数组 if(info!=null){ JSONArray jsonArray = jsonObject.getJSONArray(info); if(jsonArray.length()>0){ for(int i =0;i<jsonArray.length();i++){ String content = jsonArray.getJSONObject(i).toString(); Object o = gson.fromJson(content,clazz); sendSuccess(o,resultCallback); } } } //用于解析JSON数据中去除数组的部分 if(clazzBean!=null){ Object o = gson.fromJson(strData,clazzBean); sendSuccess(o,resultCallback); } }else { sendSuccess(str,resultCallback); } } catch (IOException e) { e.printStackTrace(); }catch (JSONException e){ e.printStackTrace(); } }else { try { ResponseBody requestBody = ProgressHelper.withProgress(response.body(),progressListener); BufferedSource bufferedSource = requestBody.source(); File file = new File(saveFilePath); file.delete(); file.getParentFile().mkdirs(); file.createNewFile(); BufferedSink sink = Okio.buffer(Okio.sink(file)); bufferedSource.readAll(sink); sink.flush(); bufferedSource.close(); }catch (Exception e){ e.printStackTrace(); } } } private void sendSuccess(final Object o, final ResultCallback resultCallback){ if(resultCallback!=null){ mHandler.post(new Runnable() { @Override public void run() { resultCallback.onSuccess(o); } }); } } private void sendFailed(final Request request, final ResultCallback resultCallback, final Exception e){ mHandler.post(new Runnable() { @Override public void run() { if(resultCallback!=null){ resultCallback.onError(request,e); }else { e.printStackTrace(); } } }); } }); }
如果下载文件则不需要设置回调,故ResultCallback设置为null,这里上传和下载文件的监听使用的是开源库https://github.com/lizhangqu/CoreProgress,在请求数据时若返回的是JSON数据,首先解析JSON数组,然后解析非数组的部分。注意这里的数据解析在子线程中运行,当解析完毕后才把数据发送给主线程回调
get请求:
public void asyncGet(String url,Header[] h,ResultCallback resultCallback,Class clazz,Class clazzBean,String info){ this.clazz = clazz; this.clazzBean = clazzBean; this.info = info; Request.Builder builder = new Request.Builder(); builder.url(url); Call call = execute(builder,h,resultCallback,url); add(url,call); }
post请求:
public void post(String url, Header[] h, ResultCallback resultCallback, List<NameValue> list,Class clazz,Class clazzBean,String info){ if(list == null){ list = new ArrayList<>(); } this.clazz = clazz; this.clazzBean = clazzBean; this.info = info; list.addAll(httpConfig.getComFiled()); FormBody.Builder form = new FormBody.Builder(); for(NameValue item:list){ form.add(item.getName(),item.getValue()); } RequestBody requestBody = form.build(); Request.Builder builder = new Request.Builder(); builder.url(url); builder.post(requestBody); Call call = execute(builder,h,resultCallback,url); add(url,call); }
上传JSON:
public void jsonPost(String url,Header[] h,ResultCallback resultCallback,Map<String,String> map,Class clazz,Class clazzBean,String info){ this.info = info; this.clazzBean = clazzBean; this.clazz = clazz; String str = gson.toJson(map); MediaType Json = MediaType.parse("application/json; charset=utf-8"); RequestBody requestBody = RequestBody.create(Json,str); Request.Builder builder = new Request.Builder(); builder.url(url); builder.post(requestBody); Call call = execute(builder,h,resultCallback,url); add(url,call); }
上传文件:
public void postFile(String url, Header[] h, ResultCallback resultCallback, Set<File> files, Class clazz, Class clazzBean, String info, String key, ProgressUIListener progressUIListener){ this.clazz = clazz; this.clazzBean = clazzBean; this.info = info; MediaType mediaType = MediaType.parse("application/octet-stream"); MultipartBody.Builder mBuilder = new MultipartBody.Builder(); mBuilder.setType(MultipartBody.FORM); if(files!=null){ for(File file:files){ mBuilder.addFormDataPart(key,file.getName(),RequestBody.create(mediaType,file)); } } RequestBody requestBody = null; if(progressUIListener!=null){//需要回调上传进度 requestBody = ProgressHelper.withProgress(mBuilder.build(),progressUIListener); }else {//不需要回调上传进度 requestBody = mBuilder.build(); } Request.Builder builder = new Request.Builder(); builder.url(url); builder.post(requestBody); Call call = execute(builder,h,resultCallback,url); add(url,call); }
下载文件:
public void downloadFile(String url,Header[] h,ResultCallback resultCallback,String saveFilePath,ProgressUIListener progressUIListener){ this.progressListener = progressUIListener; this.saveFilePath = saveFilePath; Request.Builder builder = new Request.Builder(); builder.url(url); Call call = execute(builder,h,resultCallback,url); add(url,call); }
private void add(String url,Call call){ if(!TextUtils.isEmpty(url)){ if(url.contains("?")){ url = url.substring(0,url.indexOf("?")); } cancel(url); map.put(url,call); } } private void cancel(String url){ Call call = map.remove(url); if(call!=null){ call.cancel(); } }
首先将URL和Call对象添加到map集合中,当从map中取出Call不为null时则取消请求,在第一次请求时,首先从集合中取出Call对象,由于是第一次请求故Call为null,当进行第二次相同的请求时,此时从集合中取出的是第一次请求的Call对象,故调用cancel()方法取消该请求。
全部代码OKHTTP封装2
阅读全文
0 0
- oKHttp基本封装
- OKHttp的基本使用和简单封装
- OkHttp的基本使用以及二次封装
- Okhttp的基本使用方法 及其封装
- okhttp的二次封装(基本使用)
- okhttp封装okhttp-utils
- 封装OKHttp
- 封装OkHttp
- okhttp封装
- 封装OKHttp
- 封装OKHttp
- Okhttp封装
- OkHttp 封装
- OkHttp封装
- OKHttp封装
- Okhttp封装
- okHttp封装
- OkHttp封装
- python函数
- ROS 使用sick tim561 雷达
- 验证计算和网络服务
- Python开根号
- numpy函数之numpy.ravel
- oKHttp基本封装
- Spring Boot WebMvcConfigurerAdapter 实现拦截器无配置
- Mybatis 打印SQL
- Linux修改/etc/profile文件导致进卡在登陆界面
- 2.2.QObject类功能说明和使用技巧
- OpenMP 参考(指令详解)
- Seetaface 03 Seetaface python版 win10 vs2015编译
- nginx错误反馈处理
- 对文件操作