Android項(xiàng)目基本架構(gòu)(三) Retrofit + Rx +OkHttp + MVP

image.png

前言


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對(duì)象 */
         protected V mView;
         /** Module對(duì)象 */
         @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 訂閱者對(duì)象
          */
         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都會(huì)用到的,并且使用了泛型來確定View和Module的類型。<b>注意:每次請(qǐng)求網(wǎng)絡(luò)都要調(diào)用addSub方法把Subscription對(duì)象添加到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 () {
         }
    
         /**
          * 獲取評(píng)價(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對(duì)象。

  • <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è)界面中的封裝了,對(duì)于MVP,在Activity中和在Fragment中基本上是一致的,那么接下來,我就用BaseActivity舉例。

     /**
      * Activity基類
      *
      * @author 王杰
      */
     public abstract class BaseActivity<P extends BaseMVPPresenter> extends AppCompatActivity
             implements BaseMVPView {
    
         /** Presenter對(duì)象 */
         @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對(duì)象、Module對(duì)象,我都用到了Dagger2依賴注入,創(chuàng)建后會(huì)自動(dòng)初始化。
  • 對(duì)Dagger2 不了解的朋友可以看我的上一篇文章 Android項(xiàng)目基本架構(gòu)(二) Dagger2
  • 項(xiàng)目Github地址
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容