(轉)android架構設計—mvp模式封裝

轉:https://blog.csdn.net/fanxudonggreat/article/details/79120011

簡介

關於Android程序的構架, 當前比較成熟且使用最多的應該就是MVP架構了,當然還有其他的如:MVC和MVVM。MVC相對於較爲落後,、耦合度太高、職責不明確,MVVM使用DataBind,普及性不如MVP,況且Google官方提供了Sample代碼來展示MVP模式的用法。因此選擇MVP架構毫無疑問。

概念

MVP即Model、View、Presenter

View:負責視圖部分展示、視圖事件處理。Activity、Fragment、Dialog、ViewGroup等呈現視圖的組件都可以承擔該角色。

Model:負責數據的請求、解析、過濾等數據層操作。

Presenter:View和Model交互的橋樑。

優勢

單一職責

Model、View、Presenter只處理某一類邏輯

解耦

Model層修改和View層修改互不影響

面向接口編程,依賴抽象

Presenter和View互相持有抽象引用,對外隱藏內部實現細節

可能存在的問題

Model進行異步操作,獲取結果通過Presenter回傳到View時,出現View引用的空指針異常

Presenter和View互相持有引用,解除不及時造成的內存泄漏。

因此,在進行MVP架構設計時需要考慮Presenter對View進行回傳時,View是否爲空?Presenter與View何時解除引用即Presenter能否和View層進行生命週期同步?

實現

1.首先定義兩個抽象

public interface MvpView {

}


/**
*定義P層生命週期與V層同步
*/
public interface MvpPresenter<V extends MvpView> {

void onMvpAttachView(V view, Bundle savedInstanceState);

void onMvpStart();

void onMvpResume();

void onMvpPause();

void onMvpStop();

void onMvpSaveInstanceState(Bundle savedInstanceState);

void onMvpDetachView(boolean retainInstance);

void onMvpDestroy();
}

/**
* Presenter生命週期包裝、View的綁定和解除,P層實現的基類
*/
public class BaseMvpPresenter<V extends MvpView> implements MvpPresenter<V> {

private WeakReference<V> viewRef;

protected V getView() {
return viewRef.get();
}

protected boolean isViewAttached() {
return viewRef != null && viewRef.get() != null;
}

private void _attach(V view, Bundle savedInstanceState) {
viewRef = new WeakReference<V>(view);
}

@Override
public void onMvpAttachView(V view, Bundle savedInstanceState) {
_attach(view, savedInstanceState);
}

@Override
public void onMvpStart() {

}

@Override
public void onMvpResume() {

}

@Override
public void onMvpPause() {

}

@Override
public void onMvpStop() {

}

@Override
public void onMvpSaveInstanceState(Bundle savedInstanceState) {

}

private void _detach(boolean retainInstance) {
if (viewRef != null) {
viewRef.clear();
viewRef = null;
}
}

@Override
public void onMvpDetachView(boolean retainInstance) {
_detach(retainInstance);
}

@Override
public void onMvpDestroy() {

}
}

正常情況下,開發一個項目的時候我們都會建一個BaseActivity,然後在裏面做一些共同的View層相關操作,此時如果我們將P層的初始化、與View生命週期同步放在BaseActivity裏面,很明顯會違背軟件設計原則的單一職責,且會增加耦合,不利於軟件升級、靈活性太低。因此新建一個BaseMvpActivity繼承於BaseActivity來處理P層相關。

/**
* 純粹的 MVP 包裝,不要增加任何View層基礎功能
* 如果要添加基類功能,請在{@link BaseActivity} 中添加
*/
public abstract class BaseMvpActivity<P extends MvpPresenter> extends BaseActivity implements MvpView {

protected P presenter;

protected abstract P createPresenter();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = createPresenter();
if (presenter == null) {
throw new NullPointerException("Presenter is null! Do you return null in createPresenter()?");
}
presenter.onMvpAttachView(this, savedInstanceState);
}

@Override
protected void onStart() {
super.onStart();
if (presenter != null) {
presenter.onMvpStart();
}
}

@Override
protected void onResume() {
super.onResume();
if (presenter != null) {
presenter.onMvpResume();
}
}

@Override
protected void onPause() {
super.onPause();
if (presenter != null) {
presenter.onMvpPause();
}
}

@Override
protected void onStop() {
super.onStop();
if (presenter != null) {
presenter.onMvpStop();
}
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (presenter != null) {
presenter.onMvpSaveInstanceState(outState);
}
}

@Override
protected void onDestroy() {
super.onDestroy();
if (presenter != null) {
presenter.onMvpDetachView(false);
presenter.onMvpDestroy();
}
}

}

使用

/**
* P層與V層接口定義
*/
public class MainContract {

public interface IMainView extends MvpView {

/**
* 測試
*/
void setTestContent();
}

public interface IMainPresenter extends MvpPresenter<IMainView> {

/**
* 測試
*/
void requestTestContent();
}
}

public class MainActivity extends BaseMvpActivity<MainContract.IMainPresenter> implements MainContract.IMainView {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_picker);
presenter.requestTestContent();
}

@Override
protected MainContract.IMainPresenter createPresenter() {
return new MainPresenterImpl();
}

@Override
public void setTestContent() {
Log.i(getClass().getSimpleName(), "測試成功");
}
}

public class MainPresenterImpl extends BaseMvpPresenter<MainContract.IMainView> implements MainContract.IMainPresenter {

@Override
public void requestTestContent() {
//先進行非空判斷
if (isViewAttached()) {
getView().setTestContent();
}
}

@Override
public void onMvpAttachView(MainContract.IMainView view, Bundle savedInstanceState) {
super.onMvpAttachView(view, savedInstanceState);
}

/**
*重寫P層需要的生命週期,進行相關邏輯操作
*/
@Override
public void onMvpResume() {
super.onMvpResume();
}
}

小結

Mvp模式很好的將View層和Presenter解耦,View層和Presenter層的修改互不影響,並且符合軟件設計原則之單一職責,提高了代碼的靈活性和可擴展性。最後二者之間通過抽象進行關聯,使之可以互相訪問。
————————————————
版權聲明:本文爲CSDN博主「LBJFxd」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/fanxudonggreat/article/details/79120011

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