OkHttp

https://github.com/square/okhttp

package com.yaoxin.doctor.httpservice;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.yaoxin.doctor.bean.PublicIp;
import com.yaoxin.doctor.interFace.ReqCallBack;
import com.yaoxin.doctor.utils.SharePreferenceUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import static java.lang.String.valueOf;

/**
 * 基于okhttp-3.10.0.jar进行二次封装的网络请求类
 * 

* OkHttpClient:客户端对象 * * @author Eleven */ @SuppressLint("DefaultLocale") public class MyOkHttp extends OkHttpClient { private static final String URL_PREFIX_HTTP = "http"; private static final String RESULT_SUCCESS = "0"; private static final String PLATFORM = "platform"; private static final String TOKEN = "token"; private static final String DID = "did"; private static final String PARAM_VERSION = "version"; private static final String MSG_NETWORK_ERROR = "网络错误"; private static final String MSG_CDCARD_ERROR = "文件下载出错"; private static volatile MyOkHttp mInstance;// 单利引用 private OkHttpClient mOkHttpClient;// okHttpClient 实例 private Handler okHttpHandler;// 全局处理子线程和M主线程通信 private static final String TAG = "MyOkHttp"; /** * 初始化MyOkHttp */ public MyOkHttp(Context context) { // TODO Auto-generated constructor stub // 初始化OkHttpClient mOkHttpClient = new OkHttpClient().newBuilder() .connectTimeout(10, TimeUnit.SECONDS)// 设置超时时间 .readTimeout(10, TimeUnit.SECONDS)// 设置读取超时时间 .writeTimeout(10, TimeUnit.SECONDS)// 设置写入超时时间 .addInterceptor(new LogInterceptor()) .build(); // 初始化Handler okHttpHandler = new Handler(context.getMainLooper()); } /** * 获取单例引用 * * @return */ public static MyOkHttp getInstance(Context context) { if (mInstance == null) { synchronized (MyOkHttp.class) { mInstance = new MyOkHttp(context); } } return mInstance; } // MyOkHttp.requestGetBySyn // 请求药信API GET接口,并将正确的返回值缓存到本地文件 // 参数: // url - 接口地址 // target - 缓存文件名(自动添加缓存路径) // callback - 回调 // 说明: // - 自动实例化,调用者只需使用Utils.requestGetBySyn(...)即可调用 // - target中自动添加.json后缀(防止疏忽) // - 自动添加uid与version参数到url,调用者url中无需包含 // - 已自动对返回值进行了错误判断,返回值不是JSON,或接口中返回“错误”,均自动进入onFailure处理, // 调用者无需在onSuccess中对返回值再次进行解析判断,直接拿取数据处理即可 // - 若接口返回错误(包括即便是正确的JSON,但接口中返回“错误”的情况),均不会进行本地缓存, // 即某一次的错误数据不会覆盖原有正确的缓存数据 // - onSuccess处理中,可直接使用获取结果字符串,无需再通过读取缓存文件获取结果 // - onFailure处理中,可直接使用msg参数获取错误字符串进行后续处理 public static Call requestGetBySyn(Context context, String url, String target, ReqCallBack callBack) { return MyOkHttp.getInstance(context).requestGetByAsyn(context, url, target, callBack); } // MyOkHttp.requestPostBySyn // 请求药信API POST接口, // 参数: // url - 接口地址(自动添加5iyaoxin前缀) // map - 上传数据 // callback - 回调 // 说明: // - 自动实例化,调用者只需使用MyOkHttp.requestPostBySyn(...)即可调用 // - 已自动对返回值进行了错误判断,返回值不是JSON,或接口中返回“错误”,均自动进入onFailure处理, // 调用者无需在onSuccess中对返回值再次进行解析判断,直接拿取数据处理即可 // 某一次的错误数据不会覆盖原有正确的缓存数据 // - onSuccess处理中,可直接使用获取结果字符串,无需再通过读取缓存文件获取结果 // - onFailure处理中,可直接使用msg参数获取错误字符串进行后续处理 public static Call requestPostBySyn(Context context, String url, Map map, ReqCallBack callBack) { return MyOkHttp.getInstance(context).requestPostByAsyn(context, url, map, callBack); } // MyOkHttp.requestPostFileBySyn // 请求药信API POST接口上传文件 // 参数: // url - 接口地址(自动添加5iyaoxin前缀) // map - 上传文件 // map - 上传数据 // callback - 回调 // 说明: // - 自动实例化,调用者只需使用MyOkHttp.requestPostFileBySyn(...)即可调用 // - 已自动对返回值进行了错误判断,返回值不是JSON,或接口中返回“错误”,均自动进入onFailure处理, // 调用者无需在onSuccess中对返回值再次进行解析判断,直接拿取数据处理即可 // 某一次的错误数据不会覆盖原有正确的缓存数据 // - onSuccess处理中,可直接使用获取结果字符串,无需再通过读取缓存文件获取结果 // - onFailure处理中,可直接使用msg参数获取错误字符串进行后续处理 public static Call requestPostFileBySyn(Context context, String url, File file, Map map, ReqCallBack callBack) { return MyOkHttp.getInstance(context).requestPostByFileAsyn(context, url, file, map, callBack); } // MyOkHttp.doDownloading // 下载指定url的文件到缓存路径(自动添加http前缀) // 参数: // url - 文件地址 // target - 缓存文件名(自动添加缓存路径) // callback - 回调 // 说明: // - 自动实例化,调用者只需使用MyOkHttp.doDownloading(...)即可调用 // - url中无需包含http://部分 public static Call doDownloading(Context context, String url, String target, ReqCallBack callBack) { return MyOkHttp.getInstance(context).downLoad(context, url, target, callBack); } /** * okHttp get异步请求 * * @param url 接口地址 * @param target 缓存名字 * @param callBack 请求返回数据回调 * @param 数据泛型 * @return */ @SuppressWarnings("unchecked") private Call requestGetByAsyn(final Context context, String url, String target, final ReqCallBack callBack) { try { if (!url.startsWith(PublicIp.URL) && !url.startsWith(URL_PREFIX_HTTP)) { url = PublicIp.URL + url; } // 去判断是否有用户号和版本号 url = getUrlWithExtras(context, url); if (!TextUtils.isEmpty(target)) { // 检查缓存名称是否合格 if (!target.toLowerCase().endsWith(".json")) { target = target + ".json"; } // 检查缓存名称是否包含路径 if (!target.startsWith(context.getFilesDir().getAbsolutePath())) { target = getCacheFileName(target, context); } } url = url.replace(" ",""); final String targetFileName = target; final Request request = new Request.Builder().get().url(url) .build(); final Call call = mOkHttpClient.newCall(request); if (PublicIp.URL.contains("test")) { Log.i(TAG, "requestGetByAsyn: " + url); } call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.i(TAG, "onFailure: " + e.toString()); boolean isDestoryed = false; try { Activity activity = (Activity) context; if (activity.isFinishing()) { isDestoryed = true; } } catch (Exception e1) { // TODO: handle exception } if (isDestoryed) { return; } if (!call.isCanceled()) { failedCallBack(MSG_NETWORK_ERROR, callBack); } } @Override public void onResponse(Call call, Response response) throws IOException { boolean isDestoryed = false; try { Activity activity = (Activity) context; if (activity.isFinishing()) { isDestoryed = true; } } catch (Exception e) { // TODO: handle exception } if (isDestoryed) { return; } if (response.isSuccessful()) { // 接口成功拿到数据 String result = response.body().string(); Log.i(TAG, "onResponse: " + result); /** * logout代码 */ // 辨别接口返回标识码 String error = getErrorOfReponseString(result); if (TextUtils.equals(error, "信息错误!")) { } if (error.equals(RESULT_SUCCESS) && callBack != null) { // 自动缓存数据以.json的文件存储 saveContentToFile(result, targetFileName); // 成功回调 successCallBack((T) result, callBack); } else { String errorMsg = ""; try { JSONObject obj = new JSONObject(result); if (obj.has("msg")) { errorMsg = obj.getString("msg"); } } catch (JSONException e) { e.printStackTrace(); } failedCallBack(errorMsg, callBack); } } else { String result = response.body().string(); Log.i(TAG, "onResponse: " + result); failedCallBack(MSG_NETWORK_ERROR, callBack); } } }); return call; } catch (Exception e) { return null; } } /** * okHttp post异步请求 * * @param url 接口地址 * @param map 上传数据 * @param callBack 请求返回数据回调 * @param 数据泛型 * @return */ @SuppressWarnings({"unchecked"}) private Call requestPostByAsyn(Context context, String url, Map map, final ReqCallBack callBack) { try { if (!url.startsWith(PublicIp.URL) && !url.startsWith(URL_PREFIX_HTTP)) { url = PublicIp.URL + url; } // 去判断是否有用户号和版本号 url = getUrlWithExtras(context, url); // MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM); FormBody.Builder requestBody = new FormBody.Builder(); if (map != null) { // map 里面是请求中所需要的 key 和 value for (Map.Entry entry : map.entrySet()) { requestBody.add(valueOf(entry.getKey()), valueOf(entry.getValue())); } // requestBody.add(PARAM_VERSION, getVersion(context)); // requestBody.add(PLATFORM, "Android"); // requestBody.add(TOKEN, "token"); // requestBody.add(DID, getUserId(context)); } final Request request = new Request.Builder().post(requestBody.build()) .url(url).build(); final Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { failedCallBack(MSG_NETWORK_ERROR, callBack); } @Override public void onResponse(Call call, Response response) throws IOException { Log.e(TAG, "onResponse: "+response.message().toString() ); if (response.isSuccessful()) { // 接口成功拿到数据 String result = response.body().string(); // 辨别接口返回标识码 String error = getErrorOfReponseString(result); if (error.equals(RESULT_SUCCESS) && callBack != null) { // 成功回调 successCallBack((T) result, callBack); } else { failedCallBack(error, callBack); } } else { failedCallBack(MSG_NETWORK_ERROR, callBack); } } }); return call; } catch (Exception e) { return null; } } /** * okHttp post异步请求 * * @param url 接口地址 * @param map 上传数据 * @param file 上传文件 * @param callBack 请求返回数据回调 * @param 数据泛型 * @return */ @SuppressWarnings({"unchecked"}) private Call requestPostByFileAsyn(final Context context, String url, File file, Map map, final ReqCallBack callBack) { try { if (!url.startsWith(PublicIp.URL) && !url.startsWith(URL_PREFIX_HTTP)) { url = PublicIp.URL + url; } MultipartBody.Builder requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM); if (file != null) { // MediaType.parse() 里面是上传的文件类型。 RequestBody body = RequestBody.create( MediaType.parse("image/*"), file); String filename = file.getName(); // 参数分别为, 请求key ,文件名称 , RequestBody requestBody.addFormDataPart("files", filename, body); requestBody.addFormDataPart("type", "1"); requestBody.addFormDataPart(TOKEN, SignUtils.getToken(context)); requestBody.addFormDataPart(PARAM_VERSION, getVersion(context)); requestBody.addFormDataPart(PLATFORM, "Android"); requestBody.addFormDataPart(DID, getUserId(context)); } if (map != null) { // map 里面是请求中所需要的 key 和 value for (Map.Entry entry : map.entrySet()) { requestBody.addFormDataPart(valueOf(entry.getKey()), valueOf(entry.getValue())); } } final Request request = new Request.Builder() .post(requestBody.build()).url(url).build(); final Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e("TAG", "==" + e.toString()); boolean isDestoryed = false; try { Activity activity = (Activity) context; if (activity.isFinishing()) { isDestoryed = true; } } catch (Exception e1) { // TODO: handle exception } if (isDestoryed) { return; } failedCallBack(MSG_NETWORK_ERROR, callBack); } @Override public void onResponse(Call call, Response response) throws IOException { Log.e("TAG", "==" + response.body().string()); boolean isDestoryed = false; try { Activity activity = (Activity) context; if (activity.isFinishing()) { isDestoryed = true; } } catch (Exception e) { // TODO: handle exception } if (isDestoryed) { return; } if (response.isSuccessful()) { // 接口成功拿到数据 String result = response.body().string(); // 辨别接口返回标识码 /** * logout代码 */ // 辨别接口返回标识码 String error = getErrorOfReponseString(result); if (TextUtils.equals(error, "信息错误!")) { } if (error.equals(RESULT_SUCCESS) && callBack != null) { // 成功回调 successCallBack((T) result, callBack); } else { failedCallBack(error, callBack); } } else { failedCallBack(MSG_NETWORK_ERROR, callBack); } } }); return call; } catch (Exception e) { return null; } } /** * okHttp get异步请求 * * @param url 文件地址 * @param target 下载路径 * @param callBack 请求返回数据回调 * @param 数据泛型 * @return */ @SuppressWarnings("unchecked") private Call downLoad(Context context, String url, String target, final ReqCallBack callBack) { try { // 是否添加了文件路径 if (!target.startsWith(context.getFilesDir().getAbsolutePath())) { target = getCacheFileName(target, context); } final String targetFileName = target; final Request request = new Request.Builder().get().url(url) .build(); final Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { failedCallBack(MSG_NETWORK_ERROR, callBack); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { try { // 接口成功拿到数据 // 将响应数据转化为输入流数据 InputStream inputStream = response.body() .byteStream(); FileOutputStream out = null;// 文件输出流 if (targetFileName.endsWith(".jpg")) { // 将输入流数据转化为Bitmap位图数据 Bitmap bitmap = BitmapFactory .decodeStream(inputStream); File file = new File(targetFileName); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs();// 创建文件夹 } file.createNewFile(); // 创建文件输出流对象用来向文件中写入数据 out = new FileOutputStream(file); // 将bitmap存储为jpg格式的图片 if (bitmap != null) { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); } } else { File file = new File(targetFileName); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs();// 创建文件夹 } file.createNewFile(); // 创建文件输出流对象用来向文件中写入数据 out = new FileOutputStream(file); byte[] buf = new byte[1024 * 8]; int ch; while ((ch = inputStream.read(buf)) != -1) { out.write(buf, 0, ch);// 将获取到的流写入文件中 } } // 刷新文件流 if (out != null) { out.flush(); out.close(); } successCallBack((T) targetFileName, callBack); } catch (Exception e) { // TODO: handle exception failedCallBack(MSG_CDCARD_ERROR, callBack); } } else { failedCallBack(MSG_NETWORK_ERROR, callBack); } } }); return call; } catch (Exception e) { return null; } } /** * 统一同意处理成功信息 * * @param result * @param callBack * @param */ private void successCallBack(final T result, final ReqCallBack callBack) { okHttpHandler.post(new Runnable() { @Override public void run() { if (callBack != null) { callBack.onReqSuccess(result); } } }); } /** * 统一处理失败信息 * * @param errorMsg * @param callBack * @param */ private void failedCallBack(final String errorMsg, final ReqCallBack callBack) { okHttpHandler.post(new Runnable() { @Override public void run() { if (callBack != null) { callBack.onReqFailed(errorMsg); } } }); } // 自动为在GET url中添加member_phone与version参数 public static String getUrlWithExtras(Context context, String url) { if (url.indexOf(DID) == -1) { url = getUrlWithParam(DID, getUserId(context), url); // url = getUrlWithParam(DID, getUserId(context), url); } if (url.indexOf(PARAM_VERSION) == -1) { url = getUrlWithParam(PARAM_VERSION, getVersion(context), url); } if (url.indexOf(PLATFORM) == -1) { url = getUrlWithParam(PLATFORM, "Android", url); } if (url.indexOf(TOKEN) == -1) { url = getUrlWithParam(TOKEN, SignUtils.getToken(context), url); } // String unixtime = System.currentTimeMillis() / 1000 + ""; // String sign = UtilsTool.getSign(unixtime).trim(); // // url = getUrlWithParam(UtilsTool.PARAM_UNIXTIME, unixtime, url); // url = getUrlWithParam(UtilsTool.PARAM_SIGN, sign, url); return url; } // 直接获取用户id(手机号) public static String getUserId(Context mContext) { try { SharedPreferences userinfo = mContext.getSharedPreferences( SharePreferenceUtil.SHARE_NAME, Context.MODE_PRIVATE); return userinfo.getString("userid", ""); } catch (Exception e) { return ""; } } // 获取版本号 public static String getVersion(Context context) { try { PackageInfo pi = context.getPackageManager().getPackageInfo( context.getPackageName(), 0); // 去除版本号中的逗号 String versionName = pi.versionName.replace(".", ""); return versionName; } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); return ""; } } private static String getUrlWithParam(String paramName, String paramValue, String url) { if (url.contains(paramName + "=")) { return url; } else { if (url.contains("?")) { return String.format("%1$s&%2$s=%3$s", url, paramName, paramValue); } else { return String.format("%1$s?%2$s=%3$s", url, paramName, paramValue); } } } // 获取缓存文件名 public static String getCacheFileName(String filename, Context mContext) { String cacheDir = mContext.getFilesDir().getAbsolutePath(); if (filename.startsWith("/")) { return cacheDir + filename; } else { return cacheDir + "/" + filename; } } // 将String内容保存到文件中 // 返回值: true - 成功 false - 失败 public static Boolean saveContentToFile(String content, String filename) { try { File f = new File(filename); if (!f.exists()) { f.getParentFile().mkdirs(); f.createNewFile(); } FileOutputStream ofile = new FileOutputStream(f); ofile.write(content.getBytes()); ofile.close(); return true; } catch (Exception e) { return false; } } // 返回值: // 是JSON且result=="1" 正确 result!="1" 错误:resultString // 是JSON且state=="1" 正确 state!="1" 错误:stateString // 是JSON且没有result或state 正确 // 不是JSON且返回值为"1" 正确 返回值!="1" 错误:网络错误 private static String getErrorOfReponseString(String response) { if (isJSON(response)) { try { JSONObject json = new JSONObject(response); if (json.has("result")) { return json.getString("result"); } else if (json.has("state")) { return json.getString("state"); } else if (json.has("status")) { return json.getString("status"); } else { return RESULT_SUCCESS; } } catch (JSONException e) { return RESULT_SUCCESS;// JSONArray } } else if (response.equals(RESULT_SUCCESS)) { return RESULT_SUCCESS; } else { return "网络错误"; } } // 判定字符串是否是JSONObject或JSONArray public static boolean isJSON(String content) { try { new JSONObject(content); } catch (JSONException e) { try { new JSONArray(content); } catch (JSONException c) { return false; } } return true; } }

reqcall

package com.yaoxin.doctor.interFace;

/**
 * okhttp二次封装类回调方法
 * 
 * @author Eleven
 * 
 * @param 
 */
public interface ReqCallBack {
	/**
	 * 响应成功
	 */
	void onReqSuccess(T result);

	/**
	 * 响应失败
	 */
	void onReqFailed(String errorMsg);
}

 

你可能感兴趣的:(OkHttp)