Android架構:2018 主流大廠MVP模式是怎樣?
阿新 • • 發佈:2018-11-10
1.前言
MVP
模式是目前運用最多的一種開發模式,Presenter作為Model與View的橋樑,負責業務邏輯、操作資料等工作。這樣把model與view實現了 分離(解耦合) ,有利於 結構變得更簡單 ,以便開發者更 容易管理與維護 自身的程式碼。- 雖然
MVP
具備那麼多優點,但是它不是萬能的,同樣存在一些 缺點 。 - 今天為大家分析一下主流大廠是如何解決這些缺點。
- 本文特點:圖片多,字型少
- 文章中例項 linhaojian的Github
2.目錄
3.MVP模式
3.1 介紹
MVP
3.2 作用
- 將 View 與 Model 分離,方便擴充套件與維護。
- 方便 Presenter 進行單元測試。
4.MVP缺點與解決
4.1 缺點
4.2 解決
- 4.2.1 記憶體洩漏:
1)在Presenter傳入View例項引用時,通過 弱引用 進行封裝。
2)在Presenter中提供 繫結(attach) 與 解綁(detach) 函式,以便呼叫者可以管理記憶體釋放。
/**
* 將傳入的View介面例項,通過弱引用(WeakReference)把Presenter與View進行繫結。
* @param aview 介面更新介面例項
*/
public void attach(Aview aview){
aviewWeakReference = new WeakReference<>(aview);
}
/**
* 將Presenter與View進行解綁,並釋放記憶體
*/
public void detach(){
if(aviewWeakReference!=null){
aviewWeakReference. clear();
aviewWeakReference = null;
}
}
- 4.2.2 每一個Presenter都需要編寫相同 繫結、解綁 的程式碼:
編寫一個BasePresenter類,封裝 繫結、解綁的方法。
public class BasePresenter<V> {
private WeakReference weakReference;
/**
* 將傳入的View介面例項,通過弱引用(WeakReference)把Presenter與View進行繫結。
* @param v 介面更新介面例項
*/
public void attach(V v){
weakReference = new WeakReference<>(v);
}
/**
* 將Presenter與View進行解綁,並釋放記憶體
*/
public void detach(){
if(weakReference!=null){
weakReference.clear();
weakReference = null;
}
}
}
- 4.2.3 每一個Activity都需要 初始化 Presenter與呼叫其 繫結、解綁 的方法:
編寫一個BaseActivity類,向子類提供Presenter初始化的抽象函式;並在BaseActivity中onCreate()與onDestory中呼叫對應Presenter類的attach()與detach()方法。(**提示:**Fragment同理。)
/**
* BaseActivty:封裝Presenter的繫結與解綁方法,減少相同冗餘程式碼
* @param <V> View介面
* @param <P> Presenter
*/
public abstract class BaseAcitvity<V, P extends BasePresenter<V>> extends AppCompatActivity {
private P presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = createPresenter();
if(presenter!=null){
presenter.attach((V) this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(presenter!=null) {
presenter.detach();
presenter = null;
}
}
/**
* 建立繼承於BasePresenter的子類
* @return
*/
protected abstract P createPresenter();
}
- 4.2.4 Model都是以非同步操作為主,因此可能按需編寫多個不同功能的資料回撥介面:
通過一些第三方的庫來處理該問題。
釋出事件/訂閱的框架:EventBus、RxBus、Rxjava:不一樣的詮釋
萬能介面庫:Omnipotent
- 4.2.5 Presenter與View之間的耦合度高:
舉個例子:我們app中很多介面都使用了同一個Presenter,突然收到一個需求,需要修改該Presenter的建構函式,那不是要每一個介面我都去修改一下程式碼,多浪費時間。通過 Dagger2(依賴注入庫) ,它會幫助你完成new的工作。
- 4.2.6 一個View對應多個Presenter
有時候有些介面是存在業務功能相同的情況(例如:請求的資料一樣),這時候就需要複用Presenter。
在BasePresenter新增一個列表管理需要複用的Presenter物件。
public class BasePresenter<V> {
private WeakReference weakReference;
private WeakReference<HashMap<String,BasePresenter>> weakReferenceListPresenter;
public BasePresenter(){
weakReferenceListPresenter = new WeakReference(new HashMap<>());
}
/**
* 將傳入的View介面例項,通過弱引用(WeakReference)把Presenter與View進行繫結。
* @param v 介面更新介面例項
*/
public void attach(V v){
weakReference = new WeakReference<>(v);
}
/**
* 將Presenter與View進行解綁,並釋放記憶體
*/
public void detach(){
detachPresenter();
if(weakReference!=null){
weakReference.clear();
weakReference = null;
}
}
/**
* 新增複用的Presenter例項,並將View與它們進行繫結
* @param c
* @param p
* @param <P>
*/
public <P extends BasePresenter> void addPresenter(Class<P> c,P p){
if(weakReferenceListPresenter!=null){
(weakReferenceListPresenter.get()).put(c.getName(),p);
p.attach(weakReference.get());
}
}
/**
* 通過類獲取對應的Presenter物件
* @param c
* @param <P>
* @return
*/
public <P extends BasePresenter> P getPresenter(Class<P> c){
if(weakReferenceListPresenter!=null){
return (P) (weakReferenceListPresenter.get()).get(c.getName());
}
return null;
}
/**
* View與其他Presenter進行解綁
*/
private void detachPresenter(){
if(weakReferenceListPresenter!=null){
HashMap<String,BasePresenter> map = weakReferenceListPresenter.get();
if(map!=null){
for(String name : map.keySet()){
map.get(name).detach();
}
}
}
}
5.總結
- 從 4.2.4~4.2.5 中可以發現,中間者 可以解決重複編寫資料回撥介面、耦合 的問題。
- 到此,
MVP
設計模式就分析完畢,希望能在開發過程中幫助大家。 - 如果喜歡我的分享,可以點選 關注 或者 贊,你們支援是我分享的最大動力 。
- linhaojian的Github
歡迎關注linhaojian_CSDN部落格或者linhaojian_簡書!
不定期分享關於安卓開發的乾貨。
寫技術文章初心
- 技術知識積累
- 技術知識鞏固
- 技術知識分享
- 技術知識交流