Android MVP框架簡單實現(xiàn)

Android MVP設計架構簡單實現(xiàn),其實就是為了以后編寫代碼的時候能偷懶。

1. 什么是MVP

MVP是相對MVC而言的。

MVP代表Model,View和Presenter。

  • View層負責處理用戶事件和視圖部分的展示。在Android中,它可能是Activity或者Fragment類。

  • Model層負責訪問數(shù)據(jù)。數(shù)據(jù)可以是遠端的Server API,本地數(shù)據(jù)庫或者SharedPreference等。

  • Presenter層是連接(或適配)View和Model的橋梁。

MVC與MVP的區(qū)別

MVC:

  1. Activity不僅要顯示UI,還擔任了一部分Controller的職責。
  2. 請求的業(yè)務代碼往往被丟到了Activity里面,布局文件只能提供默認的UI設置,所以開發(fā)中視圖層的變化也被丟到了Activity里面。
  3. Activity本身承擔著控制層的責任。所以Activity就成了MVC的集合,代碼嚴重耦合,維護的成本也越來越高。
  4. Model&View&Controller之間是可以相互作用的,造成嚴重的代碼耦合。

MVP:

  1. MVP與MVC最大的不同,其實是Activity職責的變化,由原來的C(控制層)變成了V(視圖層),不再管控制層的問題,只管如何去顯示。

  2. 控制層的角色就由我們的新人Presenter來擔當,這種架構就解決了Activity過度耦合控制層和視圖層的問題。

2. MVP實踐

2.1 定義契約接口

IContract主要是為了管理View和Model接口,這在你需要編寫多個View和Model時非常有用。

我們可以根據(jù)需要定義多個契約類,擴展IBaseView和IBaseModel接口以滿足實際需求。

/**
 * DESC:契約類,用于管理view和model。
 * 實現(xiàn)的view和model需要繼承實現(xiàn)其中的接口
 * <p>
 * Created by ZhangShuai on 2017/12/11.
 */
public interface IContract {

    interface IBaseView {
        void showLoading();

        void hideLoading();
        //.....定義其它一些共用的接口

    }

    interface IBaseModel {
        //.....定義一些共用的接口
    }

}

2.2 定義BasePresenter

IBasePresenter

BasePresenter在設計時考慮了RxJava。

為了防止出現(xiàn)內(nèi)存泄露,考慮了注銷信息接口。

/**
 * DESC:基礎presenter接口
 * <p>
 * Created by ZhangShuai on 2017/12/11.
 */
public interface IBasePresenter {

    //Activity關閉把view對象置為空
    void detach();

    //將網(wǎng)絡請求的每一個disposable添加進入CompositeDisposable,再退出時候一并注銷
    void addDisposable(Disposable subscription);

    //注銷所有請求
    void unDisposable();
}

BasePresenter


/**
 * DESC: 主要是用于添加、刪除view,防止內(nèi)存泄露。
 * Created by ZhangShuai on 2017/12/11.
 */
public class BasePresenter<V extends IContract.IBaseView, M extends IContract.IBaseModel> implements IBasePresenter {

    CompositeDisposable mSubscriptions;

    protected V mView;

    protected M mModel;

    public BasePresenter(V view) {
        mView = view;
    }

    protected void attach(M model) {
        this.mModel = model;
    }

    @Override
    public void detach() {
        if (this.mView != null) {
            mView = null;
        }
        unDisposable();
    }

    @Override
    public void addDisposable(Disposable subscription) {
        mSubscriptions.add(subscription);
    }

    @Override
    public void unDisposable() {
        if (mSubscriptions.isDisposed() == false) {
            mSubscriptions.dispose();
        }
    }
}

2.3 定義BaseActivity

/**
 * DESC: MVP BaseActivity
 * <p>
 * Created by ZhangShuai on 2017/12/11.
 */
public abstract class BaseActivity<P extends BasePresenter>
        extends AppCompatActivity implements IContract.IBaseView {

    protected P mPresenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = initPresenter();
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresenter != null) {
            mPresenter.detach();
            mPresenter = null;
        }
    }

    // 構造實際所需的prensenter
    public abstract P initPresenter();


}

3. 實戰(zhàn)

我們以一個登錄頁面作為實戰(zhàn)的例子。

3.1 定義契約類ILoginContract

/**
 * DESC:LoginContract
 * <p>
 * Created by ZhangShuai on 2017/12/11.
 */

public class ILoginContract {

    interface ILoginView extends IContract.IBaseView {
        // 顯示信息
        void showMsg(String msg);
    }

    interface ILoiginModel extends IContract.IBaseModel {
        // 登錄接口
        Flowable<UserInfo> login(String name, String pwd);

        void saveUserInfo(UserInfo info);
    }

}

ILoginContract使得我們設計的接口一目了然。

3.2 定義Model類

class LoginModel implements ILoginContract.ILoiginModel {

    private static String BASE_URL = "xxxxx";

    // 結合Retrofit和RxJava完成登錄
    @Override
    public Flowable<UserInfo> login(String name, String pwd) {
        Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).
                addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

        MyService api = retrofit.create(MyService.class);

        return api.login(name, pwd);
    }

    @Override
    public void saveUserInfo(UserInfo info) {
        // 保存用戶信息
    }
}

3.3 定義Presenter

class LoginPresenter extends
        BasePresenter<ILoginContract.ILoginView, ILoginContract.ILoiginModel> {


    public LoginPresenter(ILoginContract.ILoginView view) {
        super(view);
        LoginModel model = new LoginModel();
        attach(model);
    }


    public void login(String name, String pwd) {
        mView.showLoading();

        mModel.login(name, pwd)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<UserInfo>() {
                    @Override
                    public void accept(UserInfo userInfo) throws Exception {
                        mModel.saveUserInfo(userInfo);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<UserInfo>() {
                    @Override
                    public void onSubscribe(Subscription s) {

                    }

                    @Override
                    public void onNext(UserInfo userInfo) {
                        mView.showMsg("Login Successful.");
                    }

                    @Override
                    public void onError(Throwable t) {
                        mView.showMsg("Login fail.");
                        mView.hideLoading();
                    }

                    @Override
                    public void onComplete() {
                        mView.hideLoading();
                    }
                });
    }


}

3.4 定義View

其實就是Activity


public class DemoActivity extends BaseActivity<LoginPresenter> implements ILoginContract.ILoginView {

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

    @Override
    protected void onResume() {
        super.onResume();
        mPresenter.login("213", "456");
    }

    @Override
    public LoginPresenter initPresenter() {
        return new LoginPresenter(DemoActivity.this);

    }

    @Override
    public void showMsg(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();

    }

    @Override
    public void showLoading() {
        //顯示進度框
    }

    @Override
    public void hideLoading() {
        //隱藏進度框
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}


4. 總結

在簡單的設計中,MVP的代碼看起來有些復雜和冗余,但是隨著APP的功能不斷豐富,MVP將是你的不二選擇。

MVP的結構實現(xiàn)起來相對簡單,且大家在生活中經(jīng)常用到,相信通過本文章,你能更加的深入了解MVP的大致結構和框架,并在實際開發(fā)中應用起來。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 作者:李旺成 時間:2016年4月3日 “Android MVP 詳解(下)”已經(jīng)發(fā)布,歡迎大家提建議。 MVP ...
    diygreen閱讀 129,361評論 85 1,320
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • 相信大家對MVC,MVP和MVVM都不陌生,作為三個最耳熟能詳?shù)腁ndroid框架,它們的應用可以是非常廣泛的,但...
    約書亞Luis閱讀 1,313評論 0 13
  • 轉載至:http://www.itdecent.cn/p/9a6845b26856 “Android MVP 詳解...
    SnowDragonYY閱讀 10,421評論 5 241
  • 驅寒是女性的必修課,在我們生活的世界上,身體里完全沒有寒氣的女性是不存在的?!膀尯敝兴f的寒,并不僅僅指“寒癥”...
    正依閱讀 390評論 0 0

友情鏈接更多精彩內(nèi)容