package com.zenglb.framework.rxhttp; import android.content.Context; import android.content.Intent; import android.support.annotation.CallSuper; import android.util.Log; import android.widget.Toast; import com.google.gson.Gson; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import com.zenglb.baselib.utils.TextUtils; import com.zenglb.framework.activity.access.LoginActivity; import com.zenglb.framework.http.core.HttpResponse; import com.zenglb.framework.http.core.HttpUiTips; import org.reactivestreams.Subscription; import java.io.IOException; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.net.UnknownServiceException; import io.reactivex.subscribers.DisposableSubscriber; /** * Base Observer 的封装处理,对Rxjava 不熟悉,暂时先这样吧。实际的使用还不是很明白 * * 注意内存泄漏:https://github.com/trello/RxLifecycle/tree/2.x * * Created by zenglb on 2017/4/14. */ @Deprecated public abstract class BaseSubscriber<T> extends DisposableSubscriber<HttpResponse<T>> { private final String TAG = BaseSubscriber.class.getSimpleName(); private final int RESPONSE_CODE_OK = 0; //自定义的业务逻辑,成功返回积极数据 private final int RESPONSE_CODE_FAILED = -1; //返回数据失败,严重的错误 private Context mContext; private static Gson gson = new Gson(); private int errorCode; private String errorMsg = "未知的错误!"; /** * 根据具体的Api 业务逻辑去重写 onSuccess 方法!Error 是选择重写,but 必须Super ! * * @param t */ public abstract void onSuccess(T t); /** * @param mContext */ public BaseSubscriber(Context mContext) { this.mContext = mContext; HttpUiTips.showDialog(mContext, true, null); } /** * @param mContext * @param showProgress 默认需要显示进程,不要的话请传 false */ public BaseSubscriber(Context mContext, boolean showProgress) { this.mContext = mContext; if (showProgress) { HttpUiTips.showDialog(mContext, true, null); } } // @Override // public void onSubscribe(Subscription s) { // s.request(2); //what is the hell ?????? // } public BaseSubscriber() { super(); } @Override protected void onStart() { super.onStart(); } @Override public void onNext(HttpResponse<T> response) { Log.e(TAG, response.toString()); HttpUiTips.dismissDialog(mContext); if (response.getCode() == RESPONSE_CODE_OK) { onSuccess(response.getResult()); } else { Log.e(TAG, "这里有机会跑起来吗?"); onFailure(response.getCode(), response.getError()); } } @Override public void onError(Throwable t) { HttpUiTips.dismissDialog(mContext); if (t instanceof HttpException) { HttpException httpException = (HttpException) t; errorCode = httpException.code(); errorMsg = httpException.getMessage(); getErrorMsg(httpException); } else if (t instanceof SocketTimeoutException) { //VPN open errorCode = RESPONSE_CODE_FAILED; errorMsg = "服务器响应超时"; } else if (t instanceof ConnectException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "网络连接异常,请检查网络"; } else if (t instanceof RuntimeException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "运行时错误"; } else if (t instanceof UnknownHostException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "无法解析主机,请检查网络连接"; } else if (t instanceof UnknownServiceException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "未知的服务器错误"; } else if (t instanceof IOException) { //飞行模式等 errorCode = RESPONSE_CODE_FAILED; errorMsg = "没有网络,请检查网络连接"; } onFailure(errorCode, errorMsg); } /** * 简单的把Dialog 处理掉 */ @Override public void onComplete() { // HttpUiTips.dismissDialog(mContext); } /** * Default error dispose! * 一般的就是 AlertDialog 或 SnackBar * * @param code * @param message */ @CallSuper //if overwrite,you should let it run. public void onFailure(int code, String message) { if (code == RESPONSE_CODE_FAILED && mContext != null) { HttpUiTips.alertTip(mContext, message, code); } else { disposeEorCode(message, code); } } /** * 对通用问题的统一拦截处理 * * @param code */ private final void disposeEorCode(String message, int code) { switch (code) { case 101: case 112: case 123: case 401: //退回到登录页面 Intent intent = new Intent(); intent.setClass(mContext, LoginActivity.class); mContext.startActivity(intent); break; } Toast.makeText(mContext, message + " code=" + code, Toast.LENGTH_SHORT).show(); } /** * 获取详细的错误的信息 errorCode,errorMsg * <p> * 以登录的时候的Grant_type 故意写错为例子,这个时候的http 应该是直接的返回401=httpException.code() * 但是是怎么导致401的?我们的服务器会在respose.errorBody 中的content 中说明 */ private final void getErrorMsg(HttpException httpException) { String errorBodyStr = ""; try { //我们的项目需要的UniCode转码,不是必须要的! errorBodyStr = TextUtils.convertUnicode(httpException.response().errorBody().string()); } catch (IOException ioe) { Log.e("errorBodyStr ioe:", ioe.toString()); } try { HttpResponse errorResponse = gson.fromJson(errorBodyStr, HttpResponse.class); if (null != errorResponse) { errorCode = errorResponse.getCode(); errorMsg = errorResponse.getError(); } else { errorCode = RESPONSE_CODE_FAILED; errorMsg = "ErrorResponse is null"; } } catch (Exception jsonException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "http请求错误Json 信息异常"; jsonException.printStackTrace(); } } }