• 82.Android之MVP+Retrofit+RxJava实践小结


    转载:http://wuxiaolong.me/2016/06/12/mvpRetrofitRxjava/

    关于MVP、Retrofit、RxJava,之前已经分别做了分享,如果您还没有阅读过,可以猛戳:
    1、Android MVP 实例
    2、Android Retrofit 2.0使用
    3、RxJava
    4、RxBus

    假设,您对MVP、Retrofit、RxJava已经有了一点了解,那么我们开始本文:

    Android MVP优化

    1、MVP绑定Activity(Fragment)生命周期
    按照之前的文章,每个Presenter都得初始化和销毁,我新加MvpActivity(MvpFragment),加了抽象方法protected abstract P createPresenter();这样做的目的在需要使用MVP的地方,可以继承MvpActivity(MvpFragment),然后初始化和销毁就不用手动一个个去加了。

    2、接口请求等还是放到MVP的P中

    这个图片,在当时写MVP文章时给出的,实际开发中,我发现每个都这样写,实在是增加了不少代码,然接口请求放到P中,还有个好处,就是MVP绑定Activity(Fragment)生命周期,当onDestroy时取消RXJava注册,以避免内存泄露。

    代码

    目录结构

    如图,有个大致了解:

    mvp:所有的mvp都放在这个包下
    retrofit:Retrofit接口和配置文件
    rxjava:RxJava一些回调设置
    ui:Activity或fragment,建议按功能再细分包

    核心代码

    还是就贴出核心代码吧,源码在我的github上(https://github.com/WuXiaolong/AndroidMVPSample)。

    MainActivity入口,还是演示的之前的MVP的天气的接口,接口请求方法放在Presenter。

    MvpActivity

    Presenter绑定Activity(Fragment)生命周期

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public abstract class MvpActivity<P extends BasePresenter> extends BaseActivity {
    protected P mvpPresenter;
     
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    mvpPresenter = createPresenter();
    super.onCreate(savedInstanceState);
    }
     
    protected abstract P createPresenter();
     
    @Override
    protected void onDestroy() {
    super.onDestroy();
    if (mvpPresenter != null) {
    mvpPresenter.detachView();
    }
    }
    }

    MainPresenter

    apiStores.loadData方法是Retrofit做的网络请求,回调是RxJava完成的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public class MainPresenter extends BasePresenter<MainView> {
     
    public MainPresenter(MainView view) {
    attachView(view);
    }
     
    public void loadData(String cityId) {
    mvpView.showLoading();
    addSubscription(apiStores.loadData(cityId),
    new SubscriberCallBack<>(new ApiCallback<MainModel>() {
    @Override
    public void onSuccess(MainModel model) {
    mvpView.getDataSuccess(model);
    }
     
    @Override
    public void onFailure(int code, String msg) {
    mvpView.getDataFail(msg);
    }
     
    @Override
    public void onCompleted() {
    mvpView.hideLoading();
    }
    }));
    }
     
    }

    apiStores.loadData

    是不是很简单,关于Retrofit配置,详见源码AppClient。

    1
    2
    3
    4
    5
    6
    7
    8
    public interface ApiStores {
    //baseUrl
    String API_SERVER_URL = "http://www.weather.com.cn/";
     
    //加载天气
    @GET("adat/sk/{cityId}.html")
    Observable<MainModel> loadData(@Path("cityId") String cityId);
    }

    RxJava回调方法

    这里onError,写了如果网络请求用httpcode来判断。当然可以不要。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public class SubscriberCallBack<T> extends Subscriber<T> {
    private ApiCallback<T> apiCallback;
     
    public SubscriberCallBack(ApiCallback<T> apiCallback) {
    this.apiCallback = apiCallback;
    }
     
    @Override
    public void onCompleted() {
    apiCallback.onCompleted();
    }
     
    @Override
    public void onError(Throwable e) {
    e.printStackTrace();
    if (e instanceof HttpException) {
    HttpException httpException = (HttpException) e;
    //httpException.response().errorBody().string()
    int code = httpException.code();
    String msg = httpException.getMessage();
    if (code == 504) {
    msg = "网络不给力";
    }
    apiCallback.onFailure(code, msg);
    } else {
    apiCallback.onFailure(0, e.getMessage());
    }
    apiCallback.onCompleted();
    }
     
    @Override
    public void onNext(T t) {
    apiCallback.onSuccess(t);
    }
    }

    BasePresenter

    再来看看BasePresenter,这里做了Presenter初始化和销毁(包括RXjava取消注册),调用在MvpActivity。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class BasePresenter<V> implements Presenter<V> {
    public V mvpView;
    public ApiStores apiStores = AppClient.retrofit().create(ApiStores.class);
    private CompositeSubscription mCompositeSubscription;
     
    @Override
    public void attachView(V mvpView) {
    this.mvpView = mvpView;
    }
     
    @Override
    public void detachView() {
    this.mvpView = null;
    onUnsubscribe();
    }
     
    //RXjava取消注册,以避免内存泄露
    public void onUnsubscribe() {
    if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
    mCompositeSubscription.unsubscribe();
    }
    }
     
    public void addSubscription(Observable observable, Subscriber subscriber) {
    if (mCompositeSubscription == null) {
    mCompositeSubscription = new CompositeSubscription();
    }
    mCompositeSubscription.add(observable
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(subscriber));
    }
    }

    源码地址

    https://github.com/WuXiaolong/AndroidMVPSample

    总结

    三者结合使用,重点还是对MVP的优化,Retrofit只贴出最简单的(后续会写Retrofit详情使用),Rxjava可能我是对它认识尚浅,实际运用最多还是RxBus。

  • 相关阅读:
    c++ stringstream
    c语言中字符串数组初始化的一点总结&& c++访问控制的三种方式
    Leetcode 2. Add Two Numbers(medium)
    面试题---反转一个字符串
    编程题---在数组中取一个位置,让这个位置之前的数的和与之后的和的差绝对值最小
    美团面试准备
    Leetcode 101. Symmetric Tree(easy)
    Leetcode 665. Non-decreasing Array(Easy)
    617. Merge Two Binary Trees(Easy)
    423. Reconstruct Original Digits from English(Medium)
  • 原文地址:https://www.cnblogs.com/benchao/p/6242104.html
Copyright © 2020-2023  润新知