实战mvp+rxjava+retrofit框架经验之谈

前言

2016年的尾声mvp+rxjava+retrofit这套框架。可以说是风靡,但是当时的我只是在其他大神的博客中看看,没有深入了解,原因也是当时项目着急,没有精力去学习,2017年初,公司运营不善,换了新工作,0到1的项目,也使我有了实战这套风靡的框架。。。

我先说我搭建封装的结构后面有解析

关键类贴出:

 

public abstract class BasePresenterImpl<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> {

    protected T mView;
    protected CompositeSubscription mCompositeDisposable;
    protected CompositeSubscription RxBusSubscriptions;

    protected ApiStores apiStores;

    @Override
    public void attachView(T view) {
        mView = view;
        apiStores = AppClient.retrofit().create(ApiStores.class);       //retrofit初始化
        mCompositeDisposable = new CompositeSubscription();
        RxBusSubscriptions = new CompositeSubscription();
        attachView();
    }

    @Override
    public void detachView() {
        mCompositeDisposable.unsubscribe();
        RxBusSubscriptions.clear();
        RxBusSubscriptions.unsubscribe();
    }

    protected abstract void attachView();


    protected T getView() {
        return mView;
    }

    protected CompositeSubscription getSubscription() {
        return mCompositeDisposable;
    }

    @Override
    public void subscribe() {
    }

    @Override
    public void unsubscribe() {
        mCompositeDisposable.clear();
    }

    public void addSubscription(Observable observable, Subscriber subscriber) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeSubscription();
        }
        mCompositeDisposable.add(observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber));
    }

}

Presenter控制逻辑,也就是控制网络操作,绑定数据,一系列逻辑都在这.

那么,当activity关闭以后,Presenter怎么处理网络请求,异步操作呢?

比如上面的loadData(),如果acitivity已经关闭了,而网络操作又没走完.

就会内存泄漏.会不会空指针不好说.

view虽然持有p,但是也不能在Activity的onDestroy里面直接的将p=null吧

对象=null也只是断开引用而已,还并不是真的释放.

这样没用的,而且p还持有view呢,异步也不会因此结束,

所以得有个接口告诉p,我要挂了,你也自杀吧.

所以:

interface BasePresenter {

  void onStart();

   void onDestroy();

}

让所有的Presenter都继承BasePresenter,然后在activity中相应的生命周期里面调用

在相应的方法里面,初始化,结束异步操作,释放资源,将view=null;

而在activity里面,由于Presenter并没有view的引用了,

所以p随着activity的销毁也就跟着销毁了.不会造成上下文的泄漏等.

正确代码:

public interface BasePresenter<T extends BaseView> {

    void attachView(T view);

    void detachView();

    void subscribe();

    void unsubscribe();
}

在BaseActiuvity生命周期

 

@Override
protected void onResume() {
    super.onResume();
    mPresenter.subscribe();
}

@Override
protected void onStop() {
    super.onStop();
    mPresenter.unsubscribe();
}
 
@Override
protected void onDestroy() {
    super.onDestroy();
    mPresenter.detachView();
   
}

MVP设计模式

不算是个新鲜的东西了,大概解读下:

 

M层 : model 模型.

也可以理解成bean对象,我觉得不全是, 用获取数据比较贴切.

在以前写mvc的时候,我习惯抽成initData()来表示modle.

public interface Model {

  Bean load(String url,params)

}

modle,我推荐用retrofit2+rxjava来写,完全适用啊,对比一看,是不是感觉几乎没区别?

V层:view视图

在mvp中,有人把activity/fragment理解成presenter,

我觉得还是理解成v好一点,

比较纠结是,activity有生命周期,怎么就是单纯的v呢.

但如果理解成presenter的话,那么和mvc区别就不大了吧.

具体使用: 
1.写一个view接口

public interface View {

 //抽取相对的activity里面的各种行为

//如:

 void show();

 void bindData(Bean b);

}

2,activity实现这个设计好的view接口

public class MainActivity extends Activity implements View{

Presenter presenter;

@Override

 protected voidonCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState); 

           setContentView(R.layout.activity_main);

          presenter = new Presenter(this);

}

 public void show(){

 }

 public void bindData(Bean b){

      ........

     //等待数据,设置view.

 }

}

3,实现每个行为的逻辑:对某个控件做什么事.

public void show(){

//具体操作.比如弹个toast啥的,设置某个控件啥的

}

4.持有presenter

这里有点难理解,持有presenter是什么意思?

我们不管做什么操作,都是一次事件

而这个事件由谁接收,当然是activity接收了.

如果activity不持有presenter,怎么告诉presenter,我需要获得数据.

p:控制 presenter

一般写法:

public interface Presenter {

   void loadData();

}

public interface PresenterImpl implements Presenter {

 View v;

 public PresenterImpl(View v){

      this.v = v;

}

publc void loadData(){    

     Modler  modle   =    new  Modle();//创建modle

     Bean  bean =  modle.load("url",params);//获得数据 

     v.bindData(bean);//数据绑定view

}

}

总结:

presenter和view相互持有调用,presenter可以同时操作Modle和View,但是Modle和View之间不能调用.

 

Retrifit

它的作用介绍我就不多废话。

重点

public class AppClient {

    private static final String TAG = "AppClient";

    public static Retrofit mRetrofit;

    public static Retrofit retrofit() {
        if (mRetrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();

            if (BuildConfig.DEBUG) {
                // Log信息拦截器
                HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(String message) {
                        Logger.t(TAG).i(message);
                    }
                });

                logging.setLevel(HttpLoggingInterceptor.Level.BODY);
                builder.addInterceptor(logging);
            }

            OkHttpClient okHttpClient = builder.build();
            okHttpClient.networkInterceptors();
            okHttpClient.connectTimeoutMillis();
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(AppNetConfig.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(okHttpClient)
                    .build();
        }
        return mRetrofit;
    }

}

在baseactivty中初始化Presenter,接下来就是在basePresenter中初始化Retrofit了

源代码如下:别忘记在结束时取消订阅

public abstract class BasePresenterImpl<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> {

    protected T mView;
    protected CompositeSubscription mCompositeDisposable;
    protected CompositeSubscription RxBusSubscriptions;

    protected ApiStores apiStores;

    @Override
    public void attachView(T view) {
        mView = view;
        apiStores = AppClient.retrofit().create(ApiStores.class);       //retrofit初始化
        mCompositeDisposable = new CompositeSubscription();
        RxBusSubscriptions = new CompositeSubscription();
        attachView();
    }

    @Override
    public void detachView() {
        mCompositeDisposable.unsubscribe();
        RxBusSubscriptions.clear();
        RxBusSubscriptions.unsubscribe();
    }

    protected abstract void attachView();


    protected T getView() {
        return mView;
    }

    protected CompositeSubscription getSubscription() {
        return mCompositeDisposable;
    }

    @Override
    public void subscribe() {
    }

    @Override
    public void unsubscribe() {
        mCompositeDisposable.clear();
    }

    public void addSubscription(Observable observable, Subscriber subscriber) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeSubscription();
        }
        mCompositeDisposable.add(observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber));
    }

}

总结:实战中可以先简单的搭建,一点一滴的完善你的框架希望对你有所帮组。大神轻喷(一个顺手的框架史书很重要哦)有不懂的同学可以加我qq咨询425043853,答案随便写。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值