我们来看一个正常的okhttp请求:
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("bookid",String.valueOf(mBook.bookid))
.add("bookName",mBookNameEdit.getText().toString()).build();
final Request request = new Request.Builder()
.url("http://139.199.89.89/api/v1/books")
.post(body).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG,"<<<<e="+e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()) {
String d = response.body().string();
Log.d(TAG,"<<<<d="+d);
}
}
});这个有什么问题呢,第一个这个callback肯定是子线程,我们在onResponse里不能去更新UI,
还有如果对于每一个请求都要写这么一段,显得很繁琐,不够简洁,如果想往url加入一些公共参数,
显然这个也是不能实现的
那么下面我们就来封装一下这个接口:我们首先需要继承这个callback
public abstract class OkHttpResJsonHandler extends OkHttpCallback<JSONObject> {
@Override
protected JSONObject parseResponse(Response response) throws Throwable {
return responseToJson(response);
}
}private OkHttpResJsonHandler mSendListener = new OkHttpResJsonHandler() {
@Override
protected boolean isPostMainThread() {
return isBackMainThread();
}
@Override
public void onSuccess(Call call, int statusCode, Headers headers, JSONObject response) {
if (null != response) {
String status = response.optString(STATUS);
String statusMessage = response.optString(MESSAGE);
if (TextUtils.isEmpty(statusMessage)) {
setStatus(status, ApiStatus.getStatusMessage(status));
} else {
setStatus(status, statusMessage);
}
if (isSuccess()) {
try {
dismissLoading();
onParse(response);
if (null != mApiListener) {
mApiListener.success(ApiUtil.this);
}
} catch (Exception e) {
e.printStackTrace();
failure(API_STATUS_PARSE_ERROR, mContext.getString(R.string.parse_error));
}
} else {
if ("failed".equals(getStatus())) {
// 兼容data里含有message字段的api 优先级最高
JSONObject data = response.optJSONObject(DATA);
if (data != null) {
String message = data.optString(MESSAGE);
if (!TextUtils.isEmpty(message)) {
failure(status, message);
} else {
message = response.optString(MESSAGE);
if (!TextUtils.isEmpty(message)) {
failure(status, message);
} else {
failure(status, getStatusMessage());
}
}
}
}
}
} else {
failure(API_STATUS_PARSE_ERROR, mContext.getString(R.string.parse_error));
}
}
@Override
public void onFailure(Call call, int code, Headers headers, int error, Throwable t) {
if (code == 403) {
failure(API_STATUS_REJECT_ERROR, "系统繁忙,请稍后再试");
} else if (error == OkHttpCallback.RESPONSE_ERROR_SERVER) {
failure(API_STATUS_NET_ERROR, "服务器处理错误");
} else if (error == OkHttpCallback.RESPONSE_ERROR_TIMEOUT) {
failure(API_STATUS_TIMEOUT, "服务器处理错误");
} else if (error == OkHttpCallback.RESPONSE_CANCELED) {
failure(API_STATUS_CANCELED, "请求取消");
} else {
failure(API_STATUS_NET_ERROR, "亲,您的网络不给力!");
}
}
};建一个OKHttpUtil:
public static <T> void post(String url, OkRequestParams postBodyParams, Object tag, boolean isProgress, boolean commonParams, OkHttpCallback<T> okHttpCallback) {
//这里可以添加公共参数
if (commonParams) {
OkRequestParams urlComParams = new OkRequestParams();
url = getFinalUrl(url, urlComParams);
} else {
url = getFinalUrl(url, postBodyParams);
}
Call call = null;
Callback callback = getCallBack(okHttpCallback);
try {
RequestBody requestBody = (postBodyParams == null ? null : postBodyParams.getRequestBody());
Headers headers = (postBodyParams == null ? null : postBodyParams.getRequestHeaders());
Request request = getRequest(url, requestBody, headers, tag);
call = mOkHttpClient.newCall(request);
call.enqueue(callback);
} catch (Throwable e) {
e.printStackTrace();
callback.onFailure(call, new IOException("post", e));
}
}
public static Request getRequest(String url, RequestBody requestBody, Headers headers, Object tag) {
Request.Builder builder = new Request.Builder();
if (requestBody != null) {
builder.post(requestBody);
}
if (headers != null) {
builder.headers(headers);
}
if (tag != null) {
builder.tag(tag);
}
builder.url(url);
return builder.build();
}我们这样写api:
public class TestGetBookApi extends ApiUtil {
public String mData;
public TestGetBookApi() {
super();
}
@Override
protected String getUrl() {
return "http://139.199.89.89/api/v1/books";
}
@Override
protected void parseData(JSONObject jsonObject) throws Exception {
mData = jsonObject.optString(DATA);
}
}调用地方:
private void proceedBookApi() {
new TestGetBookApi().get(this, "loading", true, false, new ApiListener(){
@Override
public void success(ApiUtil api) {
Log.d(TAG,"<<<<<<success");
TestGetBookApi api1 = (TestGetBookApi)api;
if(api1.mData != null) {
mBookArrayList = new Gson().fromJson(api1.mData, new TypeToken<List<Book>>(){}.getType());
mBookMainAdapter.setList(mBookArrayList);
}
}
@Override
public void failure(ApiUtil api) {
Log.d(TAG,"<<<<<<failure");
}
});
}主体ApiUtil的完整代码是:
public abstract class ApiUtil {
public static final String API_STATUS_REJECT_ERROR = "RejectError";
public static final String API_STATUS_NET_ERROR = "NetError";
public static final String API_STATUS_PARSE_ERROR = "ParseError";
public static final String API_STATUS_NONLOGIN = "nonLogin";
public static final String API_STATUS_TIMEOUT = "timeout";
public static final String API_STATUS_CANCELED = "canceled";
private static final int STATUS_CODE_NO_NETWORK_PRE_HTTP = -1001; // 无网络状态码(不发送联网请求)
/**
* 请求参数列表
*/
private OkRequestParams mParams = new OkRequestParams();
/**
* 标签,用于扩展保存标识信息
*/
private Object mTag = null;
/**
* 状态码
*/
private String mStatus = "";
/**
* 状态码信息
*/
private String mStatusMessage = "";
/**
* 上下文
*/
private Context mContext = null;
/**
* 是否显示加载界面
*/
private boolean mShowLoading = true;
/**
* 数据返回后是否清除加载界面
*/
private boolean mDismissLoadingFinished = true;
/**
* 加载界面字符串
*/
private String mLoadingString = null;
/**
* 是否显示状态信息
*/
private boolean mShowStatusMessage = true;
/**
* API发送监听
*/
private ApiListener mApiListener = null;
/**
* 是否返回主线程
*
* @return 默认为true; 如果子类重写返回false,则不允许更新ui,且不能Toast
*/
protected boolean isBackMainThread() {
return true;
}
/**
* 发送监听
*/
private OkHttpResJsonHandler mSendListener = new OkHttpResJsonHandler() {
@Override
protected boolean isPostMainThread() {
return isBackMainThread();
}
@Override
public void onSuccess(Call call, int statusCode, Headers headers, JSONObject response) {
if (null != response) {
String status = response.optString(STATUS);
String statusMessage = response.optString(MESSAGE);
if (TextUtils.isEmpty(statusMessage)) {
setStatus(status, ApiStatus.getStatusMessage(status));
} else {
setStatus(status, statusMessage);
}
if (isSuccess()) {
try {
dismissLoading();
onParse(response);
if (null != mApiListener) {
mApiListener.success(ApiUtil.this);
}
} catch (Exception e) {
e.printStackTrace();
failure(API_STATUS_PARSE_ERROR, mContext.getString(R.string.parse_error));
}
} else {
if ("failed".equals(getStatus())) {
// 兼容data里含有message字段的api 优先级最高
JSONObject data = response.optJSONObject(DATA);
if (data != null) {
String message = data.optString(MESSAGE);
if (!TextUtils.isEmpty(message)) {
failure(status, message);
} else {
message = response.optString(MESSAGE);
if (!TextUtils.isEmpty(message)) {
failure(status, message);
} else {
failure(status, getStatusMessage());
}
}
}
}
}
} else {
failure(API_STATUS_PARSE_ERROR, mContext.getString(R.string.parse_error));
}
}
@Override
public void onFailure(Call call, int code, Headers headers, int error, Throwable t) {
if (code == 403) {
failure(API_STATUS_REJECT_ERROR, "系统繁忙,请稍后再试");
} else if (error == OkHttpCallback.RESPONSE_ERROR_SERVER) {
failure(API_STATUS_NET_ERROR, "服务器处理错误");
} else if (error == OkHttpCallback.RESPONSE_ERROR_TIMEOUT) {
failure(API_STATUS_TIMEOUT, "服务器处理错误");
} else if (error == OkHttpCallback.RESPONSE_CANCELED) {
failure(API_STATUS_CANCELED, "请求取消");
} else {
failure(API_STATUS_NET_ERROR, "亲,您的网络不给力!");
}
}
};
private void failure(String status, String statusMessage) {
dismissLoading();
setStatus(status, statusMessage);
// 特殊处理,1、当提示信息为未登陆时不弹出toast提示; 2、请求被取消
if (!status.equals(API_STATUS_NONLOGIN) && !status.equals(API_STATUS_CANCELED)) {
showStatusMessage(statusMessage);
}
if (null != mApiListener) {
try {
mApiListener.failure(ApiUtil.this);
} catch (Exception e) {
}
}
}
protected ApiUtil() {
super();
}
public Context getContext() {
if (mContext == null) {
return PicApplication.getContext();
}
return mContext;
}
/**
* 判断状态码是否成功
*
* @return
*/
public boolean isSuccess() {
return ApiStatus.isSuccess(getStatus());
}
/**
* 获取状态码
*
* @return:状态码
*/
public String getStatus() {
return mStatus;
}
/**
* 设置状态码
*
* @param status :状态码
*/
public void setStatus(String status) {
mStatus = status;
}
/**
* 获取状态信息
*
* @return:状态信息
*/
public String getStatusMessage() {
return mStatusMessage;
}
/**
* 设置状态码及错误信息
*
* @param status :状态码
* @param statusMessage :状态信息
*/
public void setStatus(String status, String statusMessage) {
mStatus = status;
mStatusMessage = statusMessage;
}
/**
* 添加参数
*
* @param key
* @param value
*/
public void addParam(String key, String value) {
mParams.put(key, value);
}
/**
* 获取url
* @return:http链接url
*/
protected abstract String getUrl();
/**
* 解析数据
*
* @param jsonObject
*/
private void onParse(JSONObject jsonObject) throws Exception {
parseData(jsonObject);
}
/**
* 解析数据
*
* @param jsonObject
*/
protected abstract void parseData(JSONObject jsonObject) throws Exception;
/**
* http post
*
* @param context :上下文
* @param loadingString :加载界面显示的提示文字, 如果传空将不显示加载界面
* @param dismissLoading :请求响应后是否销毁加载界面
* @param showStatusMessage :是否在出错时显示出错信息
* @param listener :请求响应监听
*/
public void post(Context context, String loadingString, boolean dismissLoading, boolean showStatusMessage,
ApiListener listener) {
post(context, !TextUtils.isEmpty(loadingString), loadingString, dismissLoading, showStatusMessage, listener);
}
/**
* http post
*
* @param context :上下文
* @param showLoading :是否显示加载界面
* @param loadingString :加载界面文字, 如果为空将显示默认文字
* @param dismissLoading :请求完成后是否清除加载界面
* @param showStatusMessage :是否显示出错信息
* @param listener :发送回调
*/
public void post(Context context, boolean showLoading, String loadingString, boolean dismissLoading,
boolean showStatusMessage, ApiListener listener) {
init(context, showLoading, loadingString, dismissLoading, showStatusMessage, listener);
post();
}
/**
* http get
*
* @param context :上下文
* @param loadingString :加载界面显示的提示文字, 如果传空将不显示加载界面
* @param dismissLoading :请求响应后是否销毁加载界面
* @param showStatusMessage :是否在出错时显示出错信息
* @param listener :请求响应监听
*/
public void get(Context context, String loadingString, boolean dismissLoading, boolean showStatusMessage,
ApiListener listener) {
get(context, !TextUtils.isEmpty(loadingString), loadingString, dismissLoading, showStatusMessage, listener);
}
/**
* http get
*
* @param context :上下文
* @param showLoading :是否显示加载界面
* @param loadingString :加载界面文字, 如果为空将显示默认文字
* @param dismissLoading :请求完成后是否清除加载界面
* @param showStatusMessage :是否显示出错信息
* @param listener :发送回调
*/
public void get(Context context, boolean showLoading, String loadingString, boolean dismissLoading,
boolean showStatusMessage, ApiListener listener) {
init(context, showLoading, loadingString, dismissLoading, showStatusMessage, listener);
get();
}
/**
* 无网络时模拟失败发送失败消息
*/
private void post() {
if (Util.hasNetwork(mContext)) {
OkHttpUtil.post(getUrl(), mParams, mTag, mSendListener);
} else if (mSendListener != null) {
mSendListener.onFailure(null, STATUS_CODE_NO_NETWORK_PRE_HTTP, null, OkHttpCallback.RESPONSE_ERROR_NET, new Throwable("recvfrom failed: ECONNRESET (Connection reset by peer)"));
}
}
/**
* 无网络时模拟失败发送失败消息
*/
private void get() {
if (Util.hasNetwork(mContext)) {
OkHttpUtil.get(getUrl(), mParams, mTag, mSendListener);
} else if (mSendListener != null) {
mSendListener.onFailure(null, STATUS_CODE_NO_NETWORK_PRE_HTTP, null, OkHttpCallback.RESPONSE_ERROR_NET, new Throwable("recvfrom failed: ECONNRESET (Connection reset by peer)"));
}
}
/**
* 初始化发送请求
*
* @param context :上下文
* @param showLoading :是否显示加载界面
* @param loadingString :加载界面文字, 如果为空将显示默认文字
* @param dismissLoading :请求完成后是否清除加载界面
* @param showStatusMessage :是否显示出错信息
* @param listener :发送回调
*/
private void init(Context context, boolean showLoading, String loadingString, boolean dismissLoading,
boolean showStatusMessage, ApiListener listener) {
if (null == context) {
context = PicApplication.getContext();
}
mContext = context;
mApiListener = listener;
mShowLoading = showLoading;
mLoadingString = loadingString;
mDismissLoadingFinished = dismissLoading;
mShowStatusMessage = showStatusMessage;
showLoading();
}
/**
* 设置loading对话栏显示信息
*
* @return
*/
protected String getDialogMessage() {
if (TextUtils.isEmpty(mLoadingString)) {
return mContext.getString(R.string.loading);
} else {
return mLoadingString;
}
}
/**
* 显示加载界面
*/
protected void showLoading() {
if (mShowLoading) {
DialogUtil.showLoadingDialog(mContext, getDialogMessage());
}
}
/**
* 清除加载界面
*/
protected void dismissLoading() {
// 成功时判断是否清除加载界面,失败时不判断是否清除直接清除加载界面
if ((!isSuccess()) || mDismissLoadingFinished) {
DialogUtil.dismissLoadingDialog(mContext);
}
}
/**
* 显示出错信息
*
* @param message
*/
protected void showStatusMessage(String message) {
if (mShowStatusMessage && !TextUtils.isEmpty(message)) {
Toast.makeText(mContext,message,Toast.LENGTH_SHORT).show();
}
}
protected String getString(int resId) {
String result = "";
if (null != mContext) {
result = mContext.getString(resId);
}
return result;
}
}
點擊查看更多內(nèi)容
為 TA 點贊
評論
評論
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章
正在加載中
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦