Android跟我一起來開發(fā)--微影之架構(gòu)篇

上一篇《Android跟我一起來開發(fā)--微影之開篇》中主要講述了一下寫這些博文的初衷,以及對項目中數(shù)據(jù)、架構(gòu)、框架(依賴)、目錄結(jié)構(gòu)作了一些簡單的介紹。接下來本文主要針對MVP架構(gòu)的個人理解做一個詳細的描述。當然還是站在巨人的肩膀上,我是先通讀了一下各位大神對官方mvp(基礎(chǔ)版)的分析,然后通過實際動手編寫來加深印象幫助自己更好理解。再次感謝各位大神的無私奉獻(ヽ(≧Д≦)ノ)。

說到mvp,我們不禁要思考這樣一個人生哲理:我是誰,我來自哪里,我要干什么?讓我們像剝洋蔥一層層剝開你外衣。mvp實際上就是mvc的一個變種,或者說是進化。在mvc中activity/fragment/view都是屬于view這一層,負責界面的繪制、與用戶交互,而實際上它既承擔了View的功能,同時也包含一些Controller的東西。不僅使代碼看起來臃腫,而且對于開發(fā)與維護來說都不太友好。通過把activity/fragment/view中的View和Controller剝離開來形成Presenter,專職做一些數(shù)據(jù)的處理、邏輯的控制等。在MVP中,M和V并沒有交集,兩人各自為政,互不干擾,通過P這個老好人作為中間人把三者聯(lián)系起來。通過以下兩張圖可以更清晰的理解mvc和mvp兩者之間的區(qū)別。(圖片來源)

mvc

mvp

為什么要使用mvp

  • 分離了視圖邏輯和業(yè)務(wù)邏輯,降低了耦合
  • Activity只處理生命周期的任務(wù),代碼變得更加簡潔
  • 視圖邏輯和業(yè)務(wù)邏輯分別抽象到了View和Presenter的接口中去,提高代碼的可閱讀性
  • Presenter和View被抽象成接口,可以有多種具體的實現(xiàn),所以方便進行單元測試
  • 把業(yè)務(wù)邏輯抽到Presenter中去,避免后臺線程引用著Activity導(dǎo)致Activity的資源無法被系統(tǒng)回收從而引起內(nèi)存泄露和OOM

具體用法

說到具體的用法就先來po一張目錄結(jié)構(gòu)圖上來。
目錄結(jié)構(gòu)圖

從結(jié)構(gòu)圖中不難看出,model中對應(yīng)mvp的M層,包含本地數(shù)據(jù)和遠程數(shù)據(jù)(Realm數(shù)據(jù)庫和網(wǎng)絡(luò));

base中主要是基礎(chǔ)類,其中BaseView中最主要的是setPresenter用于view持有presenter的引用。

void setPresenter(T presenter);
base

presenter包中包含了contract和presenter。其中contract是一個接口類,主要定義了繼承自baseView和basePresenter的接口,在這里聲明的接口可以一目了然,通過在V和P中進行實現(xiàn)可以使代碼更清晰簡潔易于管理。

public interface DiscoverContract {    
       interface View extends BaseView<Presenter> {        
            boolean isActive();        
            void showContent(VideoRes videoRes);        
            void refreshFaild(String msg);        
            void hidLoading();        
      }    
      interface Presenter extends BasePresenter {        
            void getData();   
      }
}

下邊是Presenter的實現(xiàn)類,可以看到在presenter的構(gòu)造方法中持有了對view的引用,同時調(diào)用了view的setPresenter方法綁定了自身使view持有了presenter的引用,這樣V和P形成了雙向引用的關(guān)系。

public class DiscoverPresenter extends RxPresenter implements DiscoverContract.Presenter {    
DiscoverContract.View mView;    
final String catalogId = "402834815584e463015584e53843000b";    
......
     public DiscoverPresenter(@NonNull DiscoverContract.View threeView) {        
          mView = Preconditions.checkNotNull(threeView);
          mView.setPresenter(this);   
       }    
    @Override    
    public void getData() {        
        getNextVideos();    
    }    
......
private void getNextVideos(){......}
}

官方mvp(基礎(chǔ)版)中是以Fragment作為View的具體載體,我沒有這么做,我是以重寫LinearLayout的自定義view作為具體的view載體。來看一下view的代碼:

public class DiscoverView extends RootView<DiscoverContract.Presenter> implements DiscoverContract.View {    
@BindView(R.id.title_name)    ColorTextView titleName;   
......
 public DiscoverView(Context context) {        super(context);    }    
 public DiscoverView(Context context, AttributeSet attrs) {        super(context, attrs);    }    
 @Override    
 protected void getLayout() {        
    inflate(mContext, R.layout.fragment_discover_view, this);    
}    
 @Override    
 public void setPresenter(DiscoverContract.Presenter presenter) {        mPresenter = com.google.common.base.Preconditions.checkNotNull(presenter);    }    
 @Override    
 public void showError(String msg) {     
   EventUtil.showToast(mContext, msg);   
 }    
 @Override    
 public void showContent(final VideoRes videoRes) {        
......
 }   
}

下面在來看一下activity頁面,代碼是不是清爽多了,View只管view,Presenter只管邏輯。

public class CollectionActivity extends SwipeBackActivity {    
@BindView(R.id.collect_view)    
CollectionView collectView;    
@Override    
protected void onCreate(Bundle savedInstanceState) {      
  super.onCreate(savedInstanceState);        
  setContentView(R.layout.activity_collection);        
  unbinder = ButterKnife.bind(this);        
  mPresenter = new CollectionPresenter(collectView, 0);    
  }
}

至此整個過程就算走完了。看到這里你可能還是云里霧里,rootview是什么啊,rxpresenter干嘛的,各個引用啥時候銷毀啊等等(哇咔咔,憋了這這么久憋出來的把自己都快搞暈了,甩甩臉,今天就到這了,下篇再針對以上問題進行補充講解,不對,自我解釋。。。)


qq交流群:138485840
下載地址:微影
源碼地址:Ghost
歡迎大家下載和Star

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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