Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android資訊 >> Android應用中MVP最佳實踐

Android應用中MVP最佳實踐

編輯:Android資訊

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

view – UI顯示層

view 層主要負責:

  1. 提供UI交互
  2. 在presenter的控制下修改UI。
  3. 將業務事件交由presenter處理。
    注意. View層不存儲數據,不與Model層交互。

presenter – 邏輯處理層

presenter 層主要負責:

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

model – 數據層

model層主要負責:

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

如圖示,裡面的activity,presenter,model均為例子:

將復雜的功能分割為各層內的小問題。各層內功能單一。這樣易於功能修改拓展與Debug。

解耦的設計,獨立的模塊,更有利於分工開發與測試。

Activity的異常重啟

Activity會在很多情況下被系統重啟:

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

正確的方式應該是:

Presenter與Activity的綁定關系應由靜態類管理。而不是由Activity管理。當Activity意外重啟時Presenter不應重啟。Activity重啟時,Presenter與Activity重新綁定,根據數據恢復Activity狀態。

而當Activity真正銷毀時。對應Presenter才應該跟隨銷毀。

這樣處理可以解決以下2個很實際的問題:

  1. 不會每次翻轉屏幕都去顯示進度條,重新加載數據。
  2. 某些低端機,調用系統拍照時內存不足,於是銷毀後台Activity。於是接受拍照返回的Activity也銷毀了。數據丟失。

生命周期

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開發過程中大量繁瑣工作。並進行了一系列優化。詳情看這裡

示例:https://github.com/Jude95/Joy

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved