Android MVP 實踐之路(一)

Android MVP 實踐之路(一)

一.簡單介紹下MVP

1.什麼是mvp?

簡稱:MVP 全稱:Model-View-Presenter ;MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供數據,View負責顯示。

2.mvp 與mvc 的區別?

在MVP中View並不直接使用Model,它們之間的通信是通過Presenter (MVC中的Controller)來進行的,所有的交互都發生在Presenter內部,而在MVC中View會直接從Model中讀取數據而不是通過 Controller。

3.優點和缺點介紹

優點:

  1. 模型與視圖完全分離,我們可以修改視圖而不影響模型
  2. 可以更高效地使用模型,因爲所有的交互都發生在一個地方——Presenter內部
  3. 我們可以將一個Presenter用於多個視圖,而不需要改變Presenter的邏輯。這個特性非常的有用,因爲視圖的變化總是比模型的變化頻繁。
  4. 如果我們把邏輯放在Presenter中,那麼我們就可以脫離用戶接口來測試這些邏輯(單元測試)

缺點:

  1. 由於對視圖的渲染放在了Presenter中,所以視圖和Presenter的交互會過於頻繁。還有一點需要明白,如果Presenter過多地渲染了視圖,往往會使得它與特定的視圖的聯繫過於緊密。一旦視圖需要變更,那麼Presenter也需要變更了。比如說,原本用來呈現Html的Presenter現在也需要用於呈現Pdf了,那麼視圖很有可能也需要變更。

二.看下實現的效果圖

三.接下來是代碼實現的過程

1.從創建開始
  1. 打開Android Studio 然後新建一個工程;
  2. 在工程中,新建三個包,分個層,分別是modle、view、presenter
  3. 思考下我們要實現的功能,模擬網絡請求,然後點擊Button,實現頁面上的TextView的文字改變,這中間我們用Handler模擬一下網絡請求
  4. 思考一下我們在MVC的時候,Activity要實現的方法:
  • 點擊按鈕請求數據
  • 當數據請求成功後,調用此接口顯示數據
  • 當數據請求失敗後,調用此接口提示
  • 當數據請求異常,調用此接口提示
  • 顯示正在加載進度框
  • 隱藏正在加載進度框
  1. 根據上面分析在MVC中所要實現的方法,我們來實現在MVP的View層的接口中需要實現這幾個方法;
public interface MvpView {
    /**
     * 顯示正在加載進度框
     */
    void showLoading();
    /**
     * 隱藏正在加載進度框
     */
    void hideLoading();
    /**
     * 當數據請求成功後,調用此接口顯示數據
     * @param data 數據源
     */
    void showData(String data);
    /**
     * 當數據請求失敗後,調用此接口提示
     * @param msg 失敗原因
     */
    void showFailureMessage(String msg);
    /**
     * 當數據請求異常,調用此接口提示
     */
    void showErrorMessage();
}	
  1. 我們的View層好像寫好了,接下來我們來想想我們的model層吧。其實很簡單,我們說了model層是數據獲取傳輸的層,那麼在model中創建個model類,然後寫一個獲取數據的靜態方法,這是獲取到數據了,那麼我們獲取到的數據怎麼傳遞給我們的Presenter呢? 不饒了,利用接口Callback方法來進行數據的回調;兩段代碼如下:

MvpModel類

public class MvpModel {
    /**
     * 獲取網絡接口數據
     *
     *
     * @param param    請求參數
     * @param callback 數據回調接口
     */
    public static void getNetData(final String param, final MvpCallback callback) {
        // 利用postDelayed方法模擬網絡請求數據的耗時操作
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                callback.onSuccess("模擬網絡請求得到的數據");
                callback.onComplete();
            }
        }, 2000);
    }
	}

MvpCallback類

public interface MvpCallback {
    /**
     * 數據請求成功
     *
     * @param data 請求到的數據
     */
    void onSuccess(String data);

    /**
     * 使用網絡API接口請求方式時,雖然已經請求成功但是由
     * 於{@code msg}的原因無法正常返回數據。
     */
    void onFailure(String msg);

    /**
     * 請求數據失敗,指在請求網絡API接口請求方式時,出現無法聯網、
     * 缺少權限,內存泄露等原因導致無法連接到請求數據源。
     */
    void onError();

    /**
     * 當請求數據結束時,無論請求結果是成功,失敗或是拋出異常都會執行此方法給用戶做處理,通常做網絡
     * 請求時可以在此處隱藏“正在加載”的等待控件
     */
    void onComplete();
    
	}
  1. 如上方法實現後,那我們的View和model層都有了,我們要實現presenter層,這個是作爲中間轉換成,要實現model層和view層的方法;所以要傳遞一個實現View接口的窗口視圖進來,然後調用model層的數據獲取方法,將model層的數據展示給我我們的view哦;啥都不說了,代碼看一眼就懂了;

MvpPresenter類

public class MvpPresenter {
    // View接口
    private MvpView mView;

    public MvpPresenter(MvpView view) {
        this.mView = view;
    }
    /**
     * 獲取網絡數據
     *
     * @param params 參數
     */
    public void getData(String params) {
        //顯示正在加載進度條
        mView.showLoading();
        // 調用Model請求數據
        MvpModel.getNetData(params, new MvpCallback() {
            @Override
            public void onSuccess(String data) {
                //調用view接口顯示數據
                mView.showData(data);
            }

            @Override
            public void onFailure(String msg) {
                //調用view接口提示失敗信息
                mView.showFailureMessage(msg);
            }

            @Override
            public void onError() {
                //調用view接口提示請求異常
                mView.showErrorMessage();
            }

            @Override
            public void onComplete() {
                // 隱藏正在加載進度條
                mView.hideLoading();
            }
        });
    }
	}
  1. 是不是很刺激?看看自己都寫了什麼❓,下面就是見證奇蹟的時刻,我們的mainActivity中應該如何編寫?佈局文件很簡單,就是一個線性佈局,裏面一個Button,一個TextView;在Activity中,要實例化Presenter類,並且那幾個方法都在Presenter中實現了哦,在來一個dialog展示框就行了,對不對?上代碼看看吧,會好理解一些;

MainActivity 類

public class MainActivity extends AppCompatActivity implements MvpView {

    private ProgressDialog progressDialog;
    private MvpPresenter presenter;
    private TextView textview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textview = findViewById(R.id.textview);
        progressDialog = new ProgressDialog(this);
        progressDialog.setCancelable(false);
        progressDialog.setMessage("正在加載數據");
        presenter = new MvpPresenter(this);

    }

    /**
     * 點擊事件
     * @param view
     */
    public void getDatas(View view) {
        presenter.getData("normal");
    }

    /**
     * 顯示正在加載進度框
     */
    @Override
    public void showLoading() {
        if (!progressDialog.isShowing()) {
            progressDialog.show();
        }
    }

    /**
     * 隱藏正在加載進度框
     */
    @Override
    public void hideLoading() {
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    /**
     * 當數據請求成功後,調用此接口顯示數據
     *
     * @param data 數據源
     */
    @Override
    public void showData(String data) {
        textview.setText(data);
    }

    /**
     * 當數據請求失敗後,調用此接口提示
     *
     * @param msg 失敗原因
     */
    @Override
    public void showFailureMessage(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * 當數據請求異常,調用此接口提示
     */
    @Override
    public void showErrorMessage() {
        Toast.makeText(this, "網絡請求數據出現異常", Toast.LENGTH_SHORT).show();
    }

	}

四.如上就是實現的過程,這是一個簡單的demo,幫助我們理解和熟悉MVP到底是什麼玩意,真的想要在項目中實踐,還需要花費一番功夫來弄。這個簡單的demo先分享給大家,更多的MVP的內容,我會在下面的文章中更新,歡迎大家一起交流,感謝大家;

最後附上一個GitHub的下載地址
https://github.com/softwareboy92/MVP

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