Android應用中MVP最佳最優實踐

所謂MVP(Model-View-Presenter)模式。是將APP的結構分爲三層:java

view - UI顯示層

view 層主要負責:android

  1. 提供UI交互
  2. 在presenter的控制下修改UI。
  3. 將業務事件交由presenter處理。

注意. View層不存儲數據,不與Model層交互。git

presenter - 邏輯處理層

presenter 層主要負責:github

  1. 對UI的各類業務事件進行相應處理。也許是與Model層交互,也許本身進行一些計算,也許控制後臺Task,Servic
    對各類訂閱事件進行響應,修改UI。
  2. 臨時存儲頁面相關數據。
  3. 注意. Presenter內不出現View引用。

model - 數據層

model層主要負責:面試

  1. 從網絡,數據庫,文件,傳感器,第三方等數據源讀寫數據。
  2. 對外部的數據類型進行解析轉換爲APP內部數據交由上層處理。
  3. 對數據的臨時存儲,管理,協調上層數據請求。

如圖示,裏面的activity,presenter,model均爲例子:
在這裏插入圖片描述數據庫

**mvp**

將複雜的功能分割爲各層內的小問題。各層內功能單一。這樣易於功能修改拓展與Debug。
解耦的設計,獨立的模塊,更有利於分工開發與測試。
Activity的異常重啓性能優化

Activity會在少數狀況下被系統重啓:

當用戶旋轉屏幕 在後臺時內存不足 改變語言設置 attache 一個外部顯示器等。

正確的方式應該是:
Presenter與Activity的綁定關係應由靜態類管理。而不是由Activity管理。當Activity意外重啓時Presenter不該重啓。Activity重啓時,Presenter與Activity從新綁定,根據數據恢復Activity狀態。
而當Activity真正銷燬時。對應Presenter才應該跟隨銷燬。
當內存不足時,Activity被銷燬實際上是整個進程被銷燬。因此Presenter也無能爲力。還原時須要重建Presenter。服務器

生命週期

Activity是一個上帝類,其實不適合做爲View。因此有些MVP方案將Activity做爲Presenter。最主要在於他的生命週期牽扯太多邏輯處理業務。這些由Presenter負責的話狀況能夠改善不少。我建議將在頂級父類中將activity的生命週期在Presenter中實現一遍,而後生命週期有關的業務邏輯直接由Presenter來實現。網絡

Model的初始化

Model不單單是javabean。Model是負責提供各種數據模型。在此基礎上我將Model拓展爲數據層提供數據交互。將javabean單獨爲數據層的一部分。
Model層的各個Model通常使用單例。這樣的好處在於這個惟一對象能夠管理一些數據供全部上層使用。
Model的單例對象架構

public class UserModel extends AbsModel{
         public static UserModel getInstance() { 
           return getInstance(UserModel.class);    
        }
            @Override
        protected void onAppCreate(Context ctx) {
            super.onAppCreate(ctx);
            //初始化
        }
    
        public void login(String number,String password,DataCallback<UserDetail> callback){
            //進行登陸請求與回調,並保存返回帳號
        }
        public void register(String tel,String password,String code,int gender,String nickname,StatusCallback callback){
            //進行註冊請求與回調
        }
    
        public void findPassword(String number,String code,String password,DataCallback<User> callback){
             //進行找回密碼請求與回調
        }
    
        public void certification(String number,String school,String realName,String stuCard,DataCallback<User> callback){
             //進行認證請求與回調
        }
    
        public void LoginOut(){
            //登出操做
        }
    
    }

既然Model層管理數據,而且是單例。他就有初始化的需求,好比在APP啓動時就請求數據,記錄信息,開始一個後臺線程與服務器同步信息等。這些操做與Presenter無關。是數據層自發的的功能。因此須要在Application啓動時進行Model的初始化。
但又要注意不能在Application的onCreate()進行過多操做,不然會啓動時間過長。因此可考慮在啓動時建立一個後臺線程,將即時性不強的初始化操做放到後臺線程。

Adapter的處理

對於Adapter是放在View好仍是Presenter好,這個問題確實難以解決。但在使用解耦的ViewHolder後這個問題便很明瞭。視圖的建立與改變全由ViewHolder管理。而後Adapter僅僅處理面向ViewHolder的邏輯。
而後ViewHolder屬於View,Adapter屬於Presenter。參考EasyRecyclerView
Adapter:

public class PersonAdapter extends RecyclerArrayAdapter<Person> {
    public PersonAdapter(Context context) {
        super(context);
    }

    @Override
    public BaseViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) {
        return new PersonViewHolder(parent);
    }
}
ViewHolder:
public class PersonViewHolder extends BaseViewHolder<Person> {
    private TextView mTv_name;
    private SimpleDraweeView mImg_face;
    private TextView mTv_sign;


    public PersonViewHolder(ViewGroup parent) {
        super(parent,R.layout.item_person);
        mTv_name = $(R.id.person_name);
        mTv_sign = $(R.id.person_sign);
        mImg_face = $(R.id.person_face);
    }

    @Override
    public void setData(final Person person){
        mTv_name.setText(person.getName());
        mTv_sign.setText(person.getSign());
        mImg_face.setImageURI(Uri.parse(person.getFace()));
    }
}

Rx的參與

Rx訂閱發佈模式在MVP中做用很大。能夠極大簡化層間通信的處理。View向Presenter訂閱數據。Presenter能夠向Model層訂閱數據。造成一個數據鏈。數據能夠直接鏈式到達View層。優雅易拓展。
Presenter

public class QuestionShowPresenter extends BeamDataActivityPresenter<QuestionShowActivity,Question> {

    @Override
    protected void onCreate(QuestionShowActivity view, Bundle savedState) {
        super.onCreate(view, savedState);
        QuestionModel.getInstance().getQuestion(1).subscribe(this);
    }
}

View

public class QuestionShowActivity extends BeamDataActivity<QuestionShowPresenter,Question> {
    @Override
    public void setData(Question data) {
        //顯示數據
    }

    @Override
    public void setError(Throwable e) {
        //顯示錯誤
    }
}

Beam

Beam是我作的一套基於MVP模式的快速開發框架。參考了nucleus。上面的示例代碼都是使用了這個(爲方便複製的這個框架demo代碼.= =)。定義了一套開發規範。並提供了基於這套規範的Activity,Fragment,Presenter,Model等父類及控件和API等,完成APP開發過程當中大量繁瑣工做。並進行了一系列優化。詳情看這裏

示例

豆逼

免費獲取安卓開發架構的資料(包括Fultter、高級UI、性能優化、架構師課程、 NDK、Kotlin、混合式開發(ReactNative+Weex)和一線互聯網公司關於android面試的題目彙總能夠加:936332305 / 連接:點擊連接加入【安卓開發架構】

相關文章
相關標籤/搜索