Android 從實現(xiàn)到封裝一個MVP

MVP之間的聯(lián)系

大概簡單的解釋就是M->module處理數(shù)據(jù)臀突,V->Act顯示界面冕香,P->M和V溝通的渠道纷捞,即P用來將數(shù)據(jù)和界面聯(lián)系到一起松靡,這樣子界面和數(shù)據(jù)就可以完全獨立開來,Act只做界面相關(guān)的事情坛增,Module只處理數(shù)據(jù)获雕,P只負責兩者溝通從而實現(xiàn)解耦。

簡單的實現(xiàn)一個沒有任何封裝的MVP

以登錄界面為例子收捣,它需要的文件大概是以下

image.png

ILoginView LoginPresenter需要和LoginAct互動的方法届案,比如說presenter需要獲得通過act登錄框的姓名,而act需要presenter處理登錄數(shù)據(jù)后的返回值code

public interface ILoginView {
    String getUserName();
    String getUserPwd();
    void onSuccess(String code);
}

IRequestLoginLoginPresenter需要和LoginModule互動的方法罢艾,比如說presenter需要通過module獲取登錄結(jié)果楣颠,而module需要presenter傳遞給他username和pwd,并傳遞一個實例化好的接口過去用來回調(diào)返回值

public interface IRequestLogin {
    void toLogin(String userName, String pwd, IRequestResult requestResult);
}

IRequestResultLoginPresenter需要實時獲取LoginModule的返回結(jié)果

public interface IRequestResult {
    
    void onSuccess(String result);

    void onFailed(String result);
    
}

3個管道定義好后就可以去實現(xiàn)3個MVP的主題module,view咐蚯,presenter

LoginAct實現(xiàn)自ILoginView接口童漩,并持有present的對象,從而實現(xiàn)LoginPresenter和它的交互,可以看到act并沒有任何處理數(shù)據(jù)的地方春锋,他要做的只是提供姓名和密碼給presenter矫膨,通過present去登錄,并且接收presenter處理后的返回值code期奔。

public class LoginAct extends AppCompatActivity implements ILoginView {
    
    private static final String TAG = "LoginAct";
    LoginPresenter loginPresenter = new LoginPresenter();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        loginPresenter.tologin(this);
    }

    @Override
    public String getUserName() {
        return "userName";
    }

    @Override
    public String getUserPwd() {
        return "userPwd";
    }

    @Override
    public void onSuccess(String code) {
        Log.e(TAG, code);
    }
    
}

LoginModule只用來做數(shù)據(jù)的處理侧馅,例如通過presenter傳遞過來的name和pwd去請求服務(wù)器從而獲取code,并通過接口返回給presenter

public class LoginModule implements IRequestLogin{

    @Override
    public void toLogin(String name, String pwd, IRequestResult requestResult) {
        requestResult.onSuccess("success->"+name+" "+pwd);
    }

}

LoginPresenter用來做兩者溝通的橋梁呐萌,他持有2個對象一個module一個view可以看出來他是中間件馁痴,用來操作module和view讓他們之間可以聯(lián)系到一起,當act發(fā)起登錄操作時肺孤,他通過view獲取到name和pwd并通過module去請求服務(wù)器拿到返回值罗晕,之后又傳遞給act。

public class LoginPresenter implements IRequestResult {
    private LoginModule loginModule;
    private ILoginView loginView;

    public void tologin(LoginAct loginAct) {
        loginView = loginAct;
        loginModule = new LoginModule();
        loginModule.toLogin(loginView.getUserName(), loginView.getUserName(), this);
    }

    @Override
    public void onSuccess(String result) {
        loginView.onSuccess(result);
    }

    @Override
    public void onFailed(String result) {

    }
    
}

簡單的實現(xiàn)后赠堵,進行封裝Base

image.png

看到3個接口不見了小渊。。因為將他們放在了BaseContract文件中顾腊,比較省事粤铭。。杂靶。contract(契約類)名字自己想一個就好。酱鸭。不用那么認真吗垮。。
BaseContract雖然沒有什么共有的因素凹髓,還是留一個base烁登,萬一以后有需求。。IBaseModule用來實現(xiàn)所有處理數(shù)據(jù)中的共同點饵沧,例如所有的module都要請求數(shù)據(jù)返回一個string

public class BaseContract {
    public interface IBaseModule {
    }

    public interface IBasePresenter {
    }

    public interface IBaseView {
        void showToast(String msg);
    }
}

BaseAct用來封裝act共有的屬性锨络,例如所有的act都會實現(xiàn)一個IBaseView接口,并且都會持有一個presenter對象狼牺,在oncreate中實例化presenter羡儿,并且實例化presenter中的module和view

public abstract class BaseAct<V extends BaseContract.IBaseView,P extends BasePresenter> extends AppCompatActivity implements BaseContract.IBaseView {

    public P presenter;

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

        if (presenter != null) {
            presenter.attatchWindow(initModule(),this);
        }

        initView();

    }

    protected abstract void initView();

    protected abstract P initPresenter();

    protected abstract BaseModule initModule();

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

BaseModule不做任何處理

public class BaseModule implements BaseContract.IBaseModule {
}

BasePresenter同時持有module和view,在actdestory的時候釋放

public class BasePresenter<M extends BaseModule, V extends BaseContract.IBaseView> {

    public M module;

    public V view;

    void attatchWindow(M m, V v) {
        this.module = m;
        this.view = v;
    }

    void detachWindow() {
        this.module = null;
        this.view = null;
    }

}

使用Base之后的Act

LoginContract和之前一樣是钥,定義需要交互的數(shù)據(jù)

public class LoginContract {

    interface ILoginView extends BaseContract.IBaseView {

        String getName();

        String getPwd();

        void onLoginResult(String code);

    }

    public interface ILoginPresenter extends BaseContract.IBasePresenter {
        void getResult(LoginBean bean);
    }

    public interface ILoginModule extends BaseContract.IBaseModule {
        void toLogin(String name, String pwd, ILoginPresenter iLoginPresenter);
    }
}

LoginAct 省去了初始化presenter的步驟

public class LoginAct extends BaseAct<LoginContext.ILoginView, LoginPresenter> implements LoginContext.ILoginView {
    private static final String TAG = "LoginAct";

    @Override
    public void showToast(String msg) {

    }

    @Override
    protected void onResume() {
        super.onResume();
        presenter.toLogin();
    }

    @Override
    protected BaseModule initModule() {
        return new LoginModule();
    }

    @Override
    protected void initView() {
    }

    @Override
    protected LoginPresenter initPresenter() {
        return new LoginPresenter();
    }

    @Override
    public String getName() {
        return "name";
    }

    @Override
    public String getPwd() {
        return "pwd";
    }

    @Override
    public void onLoginResult(String code) {
        Log.e(TAG, code);

    }
}

LoginModule請求數(shù)據(jù)返回結(jié)果掠归,差別不大

public class LoginModule extends BaseModule implements LoginContract.ILoginModule {

    @Override
    public void toLogin(String name, String pwd, LoginContract.ILoginPresenter iLoginPresenter) {
        //網(wǎng)絡(luò)操作,返回數(shù)據(jù)
        LoginBean loginBean = new LoginBean();
        loginBean.setCode(name + pwd);
        iLoginPresenter.getResult(loginBean);
    }

}

LoginPresenter省去實例化module和view的步驟

public class LoginPresenter extends BasePresenter<LoginModule, LoginAct> implements LoginContract.ILoginPresenter {

    public void toLogin() {

        module.toLogin(view.getName(), view.getPwd(), this);

    }

    @Override
    public void getResult(LoginBean bean) {
        view.onLoginResult(bean.getCode());
    }

}

綜上就是從實現(xiàn)到封裝一個mvp的簡易過程悄泥。虏冻。。但是優(yōu)化的道路還很漫長弹囚。厨相。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鸥鹉,隨后出現(xiàn)的幾起案子蛮穿,更是在濱河造成了極大的恐慌,老刑警劉巖宋舷,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绪撵,死亡現(xiàn)場離奇詭異,居然都是意外死亡祝蝠,警方通過查閱死者的電腦和手機音诈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绎狭,“玉大人细溅,你說我怎么就攤上這事±芩唬” “怎么了喇聊?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蹦狂。 經(jīng)常有香客問我誓篱,道長,這世上最難降的妖魔是什么凯楔? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任窜骄,我火速辦了婚禮,結(jié)果婚禮上摆屯,老公的妹妹穿的比我還像新娘邻遏。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布准验。 她就那樣靜靜地躺著赎线,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糊饱。 梳的紋絲不亂的頭發(fā)上垂寥,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天,我揣著相機與錄音济似,去河邊找鬼矫废。 笑死,一個胖子當著我的面吹牛砰蠢,可吹牛的內(nèi)容都是我干的蓖扑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼台舱,長吁一口氣:“原來是場噩夢啊……” “哼律杠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起竞惋,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤柜去,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拆宛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗓奢,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年浑厚,在試婚紗的時候發(fā)現(xiàn)自己被綠了股耽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡钳幅,死狀恐怖物蝙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敢艰,我是刑警寧澤诬乞,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站钠导,受9級特大地震影響震嫉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牡属,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一责掏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧湃望,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至废士,卻和暖如春叫潦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背官硝。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工矗蕊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氢架。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓傻咖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親岖研。 傳聞我的和親對象是個殘疾皇子卿操,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容