實戰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,答案隨便寫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章