美文网首页
Retrofit的设计模式 -- 静态代理模式

Retrofit的设计模式 -- 静态代理模式

作者: gzfgeh | 来源:发表于2017-01-10 22:54 被阅读41次

    今天用代理模式完美解决公司项目的bug.

    BUG代码

    用RxJava封装的网络请求统一处理方案

    public abstract class RxSubUtils<T> extends Subscriber<T> {
        private CompositeSubscription mCompositeSubscription; 
        private Context mContext;    
        private String msg;   
     
        public RxSubUtils(){}    
        public RxSubUtils(CompositeSubscription mCompositeSubscription) {
            this.mCompositeSubscription = mCompositeSubscription;
        }
        /**
         * @param context context
         * @param msg     dialog message
         */
        public RxSubUtils(CompositeSubscription mCompositeSubscription, Context context, String msg) {
            this.mCompositeSubscription = mCompositeSubscription;
            this.mContext = context;
            this.msg = msg;
        }
        /**
         * @param context context
         */
        public RxSubUtils(CompositeSubscription mCompositeSubscription, Context context) {
            this(mCompositeSubscription, context, "请稍后...");
        }
        /**
         * 这个一定要有 Presenter的逻辑在这里处理
         * @param t
         */
        @Override
        public void onNext(T t) {
            _onNext(t);
        }
        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
            LoadingDialogManager.getLoadingDialog().hideDialog();
            if (!NetWorkUtils.isNetworkAvailable()) {
                ToastUtil.show(R.string.net_error);
            } else if (e instanceof RxUtils.ServerException) {//
                String s = ((RxUtils.ServerException)e).getMsg();//
                //token 过期了
                //if(TextUtils.equals(s, RxUtils.TOKEN_OVER_TIME) && mContext != null){
    //                Utils.startLoginActivity(mContext);
    //            }
    //            ToastUtil.show(s);
            } else {
                ToastUtil.show(R.string.error);
            }
            _onError();
        }
        @Override
        public void onCompleted() {
            if (mCompositeSubscription != null)
                mCompositeSubscription.remove(this);
            LoadingDialogManager.getLoadingDialog().hideDialog();
        }
        @Override
        public void onStart() {
            super.onStart();
            if (mContext != null) {
                LoadingDialogManager.getLoadingDialog().showDialog(mContext);
            }
        }
        protected abstract void _onNext(T t);
        /**
         * 错误处理,需要的话重写这个方法
         */
        protected void _onError(){
        }
    }
    

    1.统一处理网络请求到的数据
    2.可以选择是否添加LoadingDialog
    3.可以统一处理特殊情况,如用户信息过期等
    使用方法:

    public void getDataList(){
        mCompositeSubscription.add(model.getDataList()
                .subscribe(new RxSubUtils<List<VideoBean>>(mCompositeSubscription) {
                    @Override
                    protected void _onNext(List<VideoBean> videoBeen) {
                        getView().getVideoList(videoBeen);
                    }
                    @Override
                    protected void _onError() {
                        getView().onFail();
                    }
                }));
    }
    

    以上封装只是部分代码,主要不是说明这个问题,APP跑起来,切换各种网络,2G,3G,wifi但访问不到后台数据,wifi能正常访问等操作,就会出现下面bug。
    Stack trace is opaque for IllegalStateException: Exception thrown on Scheduler.Worker thread. Add onError handling.
    看到最后说到解决方法两种:

    1. 一种是上面的RxSubUtils改为继承SafeSubscriber
    2. 一种是在使用的时候加上Throwable的处理

    那么问题来了,第二种方法中上面的使用方法有成百上千个,真是不能手工一个一个改,会死人的,所以就只能用第一种方法,但是第一种方法中继承SafeSubscriber,构造函数就要改变,使用的时候还是每一个地方都要改,还是会死人

    -----------------------------------------分割线-----------------------------------------

    解决方案:

    建立RxSafeSubUtils类继承SafeSubscriber,设置为被代理类,原来的RxSubUtils设置为代理类,改为如下

    
    public class RxSafeSubUtils<T> extends SafeSubscriber<T> {
    
        private CompositeSubscription mCompositeSubscription;
        private Context mContext;
        private IOSDialog dialog;
        private Subscription subscription;
    
        public RxSafeSubUtils(Subscriber<? super T> actual) {
            super(actual);
            subscription = actual;
        }
    
        public RxSafeSubUtils(Subscriber<? super T> actual, CompositeSubscription compositeSubscription) {
            super(actual);
            this.mCompositeSubscription = compositeSubscription;
            subscription = actual;
        }
    
        public RxSafeSubUtils(Subscriber<? super T> actual, CompositeSubscription compositeSubscription, Context context) {
            this(actual, compositeSubscription);
            this.mContext = context;
            subscription = actual;
        }
    
    
        /**
         * 这个一定要有 Presenter的逻辑在这里处理
         * @param t
         */
        @Override
        public void onNext(T t) {
            ((RxSubUtils)subscription).onNext(t);
        }
    
        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
            if (!NetWorkUtils.isNetworkAvailable()) {
                ToastUtil.show(R.string.net_error);
            } else if (e instanceof RxUtils.ServerException) {
                String s = ((RxUtils.ServerException)e).getMsg();
                //token 过期了
                if(TextUtils.equals(s, RxUtils.TOKEN_OVER_TIME) && mContext != null){
                    Utils.startLoginActivity(mContext);
                }
                ToastUtil.show(s);
            } else {
                ToastUtil.show(R.string.error);
            }
    
            if (dialog!= null){
                dialog.dismiss();
                dialog = null;
            }
            ((RxSubUtils)subscription)._onError();
        }
    
        @Override
        public void onCompleted() {
            if (mCompositeSubscription != null)
                mCompositeSubscription.remove(this);
    
            if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            }
        }
    
        @Override
        public void onStart() {
            super.onStart();
            if (mContext != null && dialog == null) {
                dialog = new IOSDialog(mContext).builder()
                        .setLoadingView(R.color.colorPrimary);
                dialog.show();
            }
        }
    }
    
    
    public abstract class RxSubUtils<T> extends Subscriber<T> {
        private RxSafeSubUtils<T> rxSafeSubUtils;
    
        public RxSubUtils() {
            rxSafeSubUtils = new RxSafeSubUtils<T>(this);
        }
    
        public RxSubUtils(CompositeSubscription mCompositeSubscription) {
            rxSafeSubUtils = new RxSafeSubUtils<T>(this, mCompositeSubscription);
        }
    
        /**
         * @param context context
         */
        public RxSubUtils(CompositeSubscription mCompositeSubscription, Context context) {
            rxSafeSubUtils = new RxSafeSubUtils<T>(this, mCompositeSubscription, context);
        }
    
        /**
         * 这个一定要有 Presenter的逻辑在这里处理
         * @param t
         */
        public void onNext(T t) {
            _onNext(t);
        }
    
        @Override
        public void onError(Throwable e) {
            _onError();
        }
    
        @Override
        public void onCompleted() {
            rxSafeSubUtils.onCompleted();
        }
    
        @Override
        public void onStart() {
            rxSafeSubUtils.onStart();
        }
    
        protected abstract void _onNext(T t);
    
        /**
         * 错误处理,需要的话重写这个方法
         */
        protected void _onError(){
    
        }
    
    }
    
    
    

    这样用的时候, 代码什么都不改,完美解决!
    PS:最好的方法还是在开始的时候就想到封装RxSafeSubUtils,不用任何代理!

    相关文章

      网友评论

          本文标题:Retrofit的设计模式 -- 静态代理模式

          本文链接:https://www.haomeiwen.com/subject/lqslbttx.html