前言
- 好了哈扮,接下來就要和大家說說 Retrofit + Rx +OkHttp + MVP 了纬纪,這些都是老套路了,關(guān)于Retrofit + Rx 的用法灶泵,我已經(jīng)在之前的文章里面講解過了育八,不知道的朋友可以先移步看看:
- Android中用Retrofit+Rxjava搭建網(wǎng)絡(luò)請求
- Retrofit的深入使用
- 那么,今天的重點(diǎn)就是MVP模式的構(gòu)建了赦邻。
MVP實(shí)現(xiàn)
關(guān)于MVP和MVC相關(guān)的概念相信大家都知道髓棋,就算不知道的百度一下也有很多,這里就不多說了惶洲,重點(diǎn)是如何實(shí)現(xiàn)這樣的架構(gòu)按声,并且使用起來方便。
-
首先恬吕,是相關(guān)的基類的創(chuàng)建 BaseMVPPresenter签则、BaseMVPView。不多說铐料,上代碼
/** * MVP Presenter基類 * * @param <V> MVP View 繼承 {@link BaseMVPView} * @param <M> MVP Module * * @author 王杰 */ public class BaseMVPPresenter<V extends BaseMVPView, M> { /** View對象 */ protected V mView; /** Module對象 */ @Inject protected M mModule; /** Rx生命周期管理 */ private CompositeSubscription subscriptions; protected BaseMVPPresenter() { subscriptions = new CompositeSubscription(); } /** * 綁定View * * @param view MVP View */ public void onAttach(V view) { mView = view; } /** * 解綁MVP View */ void onDetach() { mView = null; } /** * 添加到生命周期管理 * * @param sub 訂閱者對象 */ protected void addSub(Subscription sub) { if (subscriptions == null) { return; } if (sub != null) { subscriptions.add(sub); } } /** * 解綁訂閱者 */ void unSubscribe() { if (subscriptions == null) { return; } if (subscriptions.hasSubscriptions()) { subscriptions.unsubscribe(); } } }
-
在BaseMVPPresenter中渐裂,我定義一些方法豺旬,包括綁定解綁View、Rx生命周期管理柒凉,這幾個(gè)方法是每個(gè)Presenter都會用到的族阅,并且使用了泛型來確定View和Module的類型。<b>注意:每次請求網(wǎng)絡(luò)都要調(diào)用addSub方法把Subscription對象添加到Rx生命周期膝捞。</b>
/** * Presenter實(shí)現(xiàn)類 * * @author 王杰 */ public class ImpPresenter extends BaseMVPPresenter<ImpView, ImpModule> { @Inject ImpPresenter() { super(); } public void doSomething() { Subscription sub = mModule.doSomething( data -> { // 獲取數(shù)據(jù)成功 mView.notifyData(data); }, throwable -> { // 獲取數(shù)據(jù)失敗 mView.showToast("Net Error!"); }); // 添加到生命周期 addSub(sub); } }
構(gòu)造方法調(diào)用父類構(gòu)造方法坦刀,多個(gè)Module也可以在這里初始化。
-
<b>構(gòu)造方法使用@Inject注解蔬咬, 使用Dagger2</b>
/** * Module實(shí)現(xiàn)類 * * @author 王杰 */ public class ImpModule { @Inject ImpModule () { } /** * 獲取評價(jià)最高電影 */ public Subscription doSomething(Action1<Bean> success, Action1<Throwable> throwable) { return RXClientGenerator.getInstance().createClient() .doSomething() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(success, throwable); } }
在Module中定義方法獲取數(shù)據(jù)等操作鲤遥,返回Subscription對象。
-
<b>由于BaseMVPPresenter中Module使用@Inject注解進(jìn)行初始化林艘,所有Module的構(gòu)造方法必須使用@Inject注解</b>
/** * MVP View基類 * * @author 王杰 */ public interface BaseMVPView { /** * Toast提示 * * @param str 提示文本 */ void showToast(String str); /** * Toast提示 * * @param strResId 提示文本id */ void showToast(@StringRes int strResId); }
在BaseMVPView中盖奈,定義了彈出Toast的方法,可以讓BaseActivity和BaseFragment實(shí)現(xiàn)這個(gè)接口狐援,并且實(shí)現(xiàn)這兩個(gè)方法卜朗,這樣的話,在Activity實(shí)現(xiàn)View接口的時(shí)候就不用重寫也能完成相關(guān)功能咕村。當(dāng)然了场钉,你可以把你項(xiàng)目中大多數(shù)界面需要用到的操作定義在這個(gè)接口里,并在Activity懈涛、Fragment的基類實(shí)現(xiàn)逛万。
而關(guān)于Module則是獲取數(shù)據(jù)保存數(shù)據(jù)等操作,暫時(shí)沒有發(fā)現(xiàn)有共用的功能批钠,所以沒有封裝宇植。
進(jìn)一步封裝
-
MVP的基類都定義好了,那么接下來就是在各個(gè)界面中的封裝了埋心,對于MVP指郁,在Activity中和在Fragment中基本上是一致的,那么接下來拷呆,我就用BaseActivity舉例闲坎。
/** * Activity基類 * * @author 王杰 */ public abstract class BaseActivity<P extends BaseMVPPresenter> extends AppCompatActivity implements BaseMVPView { /** Presenter對象 */ @Inject protected P presenter; @Override protected void onDestroy() { super.onDestroy(); // Rx生命周期管理 if (presenter != null) { presenter.onDetach(); presenter.unSubscribe(); } } @Override public void showToast(String str) { Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show(); } @Override public void showToast(@StringRes int strResId) { Toast.makeText(mContext, strResId, Toast.LENGTH_SHORT).show(); } }
使用泛型確定Presenter的類型,實(shí)現(xiàn)BaseMVPView茬斧,并且實(shí)現(xiàn)其中定義的方法腰懂。在界面銷毀時(shí),解綁View项秉,結(jié)束Rx生命周期绣溜。
總結(jié)
- 項(xiàng)目中的MVP大概就是這樣了,實(shí)際上關(guān)于Presenter以及Module都可以向上抽取成接口娄蔼,使用者持有接口調(diào)用方法怖喻。但是由于項(xiàng)目中使用了Dagger2依賴注入底哗,無法將接口初始化為實(shí)現(xiàn)類,而且那樣做需要新建的類又太多了锚沸,所以并沒有抽取艘虎。
- 這里的Presenter對象、Module對象咒吐,我都用到了Dagger2依賴注入,創(chuàng)建后會自動初始化属划。
- 對Dagger2 不了解的朋友可以看我的上一篇文章 Android項(xiàng)目基本架構(gòu)(二) Dagger2
- 項(xiàng)目Github地址