美文网首页
Retrofit 2 + RxAndroid实践记录

Retrofit 2 + RxAndroid实践记录

作者: Jin丶破 | 来源:发表于2016-08-16 10:39 被阅读240次

    在这Rx流行的时代,我也接触一段时间了,便通过这篇文章记录下Retrofit 2 + RxAndroid的一些实践记录(这里记录客户端网络请求的实践)。

    定义Response基类

    根据接口返回响应结果定义一个BaseRes类。
    我接口返回的数据格式如下:

    Paste_Image.png

    BaseRes定义如下,需对应。

    public class BaseRes<T> {
        public int showapi_res_code;
        public String showapi_res_error;
        public T showapi_res_body;
    }
    
    定义Service Method
    public interface ApiService {
        /**     * 获取笑话列表
         *
         * @return
         */
        @GET("showapi_open_bus/showapi_joke/joke_text")
        Observable<BaseRes<JokeInfo>> getJokes(@Query("page") int page);
    }
    

    其中JokeInfo是BaseRes中泛型的具体实现,是根据获取的数据具体定义的(看后面demo上)

    创建Retrofit实例,并创建Service Method

    根据需要定义OkHttpClient,然后实例Retrofit,并创建Service Method。

    public class ApiClient {
        public static final String BASE_URL = "http://apis.baidu.com/";
        private static Retrofit mRetrofit;
        private static OkHttpClient.Builder mClientBuilder;
        public ApiService mApiService;
        static {
            mClientBuilder = new OkHttpClient.Builder();
            /** *设置缓存,代码略 */
    
            /** *公共参数,代码略 */
    
            /** * 设置头,代码略 */
    
            /** * Log信息拦截器,代码略 */
    
            /** * 设置cookie,代码略 */
    
            /** * 设置超时和重连,代码略 */
        }
        private ApiClient() {
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(mClientBuilder.build())
                    .build();
            mApiService = mRetrofit.create(ApiService.class);
        }
        //在访问HttpMethods时创建单例
        private static class SingletonHolder {
            private static final ApiClient INSTANCE = new ApiClient();
        }
        //获取单例
        public static ApiClient getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }
    
    线程调度管理

    基本我们都是在io上发请求,在主线程上处理响应和界面交互,所以定义一个默认的线程调度类(当然为了更好的处理,io线程也可以自己定义,这里使用默认的Schedulers.io())。

    public class SchedulerTransformer<T> implements Observable.Transformer<T,T> {
        @Override
        public Observable<T> call(Observable<T> observable) {
            return observable
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
        }
        public static <T> SchedulerTransformer<T> create() {
            return new SchedulerTransformer<>();
        }
    }
    
    封装Subscriber

    为了统一处理错误和一些加载效果之类的操作,定义BaseSubscriber和LoadingSubscriber对Subscriber封装。

    public abstract class BaseSubscriber<T extends BaseRes> extends Subscriber<T> {
        private Context mContext;
        public BaseSubscriber() {
        }
        public BaseSubscriber(Context context) {
            mContext = context;
        }
        public Context getContext() {
            return mContext;
        }
        @Override
        public void onCompleted() {
        }
        @CallSuper
        @Override
        public void onError(Throwable e) {
            /** 根据异常处理错误信息 */
            ToastUtil.showShort(getContext(), NetworkUtils.getMsgByError(e));
        }
        @Override
        public void onNext(T t) {
            if (t.showapi_res_code == Const.CODE_SUCCESS) {
                _onNext(t);
            } else {
                ToastUtil.showShort(mContext, t.showapi_res_error);
            }
        }
        public abstract void _onNext(T entity);
    }
    

    LoadingSubscriber继承BaseSubscriber,然后重写OnStart(),onCompleted(),onError()方法,再自己去处理逻辑,这里就不贴代码了,当然,如果还需其他统一处理也可以类似去实现自己想要的Subscriber,比如DialogSubscriber。

    使用

    这里我通过百度api上的易源_笑话大全接口作为例子说明使用Retrofit + RxAndroid实现请求网络并在界面上展现。

    1、定义笑话类JokeInfo

    代码有点长,就不贴出来了,看后面链接上的Demo。

    2、MVP实现获取数据

    首先定义一个契约接口统一管理该模块的Presenter,Model,View。

    public interface InfoContract {
        interface Model extends BaseModel {
            Observable<BaseRes<JokeInfo>> getJokes(int page);
        }
        interface View extends BaseView {
            void loadList(List<JokeInfo.JokeContent> jokeContents, int pageCount);
        }
        abstract class Presenter extends BasePresenter<Model, View> {
            public abstract void getJokes(int page);
            @Override
            public void onStart() {
    
            }
        }
    }
    

    (这里的BaseModel,BaseView,BasePresenter看Demo)
    定义Model继承InfoContract.Model,返回Observable,然后在InfoPresenter中订阅。

    public class InfoModel implements InfoContract.Model {
        @Override
        public Observable<BaseRes<JokeInfo>> getJokes(int page) {
            return ApiClient.getInstance().mApiService
                    .getJokes(page)
                    .compose(SchedulerTransformer.<BaseRes<JokeInfo>>create());
        }
    }
    
    public class InfoPresenter extends InfoContract.Presenter {
        @Override
        public void getJokes(int page) {
            mRxManage.add(mModel.getJokes(page)
            .subscribe(new LoadingSubscriber<BaseRes<JokeInfo>>(mContext) {
                @Override
                public void _onNext(BaseRes<JokeInfo> entity) {
                    mView.loadList(entity.showapi_res_body.getContentlist(),
                            entity.showapi_res_body.getAllPages());
                }
            }));
        }
    }
    
    3、界面上实现

    在onCreate里面初始化MVP

    mPresenter = new InfoPresenter();
    mModel = new InfoModel();
    mPresenter.setVM(mModel, this, this);  // 第一个this是回调View,第二个this是Context
    

    在需要获取数据的地方执行

    mPresenter.getJokes(page);
    

    进行获取数据。
    在View回调上处理返回的数据,并展现到界面上。

    总结

    通过以上实践,是否发现Retrofit + RxAndroid 大大改善了代码的可维护性,代码逻辑清晰了然。

    附Demo地址

    Demo

    参考阅读

    T-MVP
    Retrofit + RxAndroid 实践总结

    相关文章

      网友评论

          本文标题:Retrofit 2 + RxAndroid实践记录

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