Android開發(fā)之Dagger2--MVP模式中使用(四)

前言

在上一篇文章里Android開發(fā)之Dagger2--Module&Component(三),主要分析了Dagger2注入過程现横,Module和Component各有什么作用漓拾,使用的例子也是很簡單的。前面曾經(jīng)提到過戒祠,Dagger2最適合在mvp模式中使用骇两,那這位篇文章就是應用在mvp模式中。對mvp模式不了解的可以參照 Android架構(gòu)--MVC姜盈、MVP低千、MVVMMVP模式--登錄馏颂,這一篇文章就是在第二篇文章的基礎上引入了Dager2示血。

廢話不說,直接上代碼 源碼傳送門

代碼

1 .View

mvp模式的view部分救拉,我把它放在一個接口里面难审,當然可以單獨為登錄模塊寫一個View接口,考慮到每個界面有可能都會有個View接口亿絮,所以我把它們放在一個IView接口里告喊,這樣可以減少接口文件的數(shù)量。
view的主要作用是
1.接收用戶請求派昧,并把請求傳遞給Presenter層處理葱绒。
2.Presenter操作View層更新數(shù)據(jù)

  • 對于登錄模塊來說,getUserName()斗锭,getPassWord()方法分別是接收用戶名和密碼的,屬于接收用戶請求部分失球,在Presenter里這兩個方法會被調(diào)用岖是,實現(xiàn)將用戶請求傳遞給Presenter層。
  • closeDispose(Disposable disposable)实苞,toOtherActivity()方法則是數(shù)據(jù)請求成功后豺撑,Presenter操作View層進行數(shù)據(jù)更新
public class IView {

    /**
     * 登錄
     */
    public interface ILoginView {
        String getUserName();
        String getPassWord();
        void showToast(String content);
        void closeDispose(Disposable disposable);
        void showProgress();
        void hideProgress();
        void toOtherActivity();
    }
}

ILoginView 接口里定義的方法,最終是要在View模塊實現(xiàn)的黔牵,不同于在傳統(tǒng)的MVC模式聪轿,在MVC模式里,Activity既是View層猾浦,又是Model層陆错,在MVP里灯抛,Activity則完全充當了View的角色。
所以在要Activity里實現(xiàn)ILoginView 接口音瓷。

public class LoginActivity extends BaseActivity implements IView.ILoginView {
}
2. Model

Model層的作用如下:

  • 接受Presenter的請求進行數(shù)據(jù)更新
  • 更新完成后通知Presenter數(shù)據(jù)更新完畢对嚼,Presenter再去通知View進行界面更新
    很明顯,Model層就是數(shù)據(jù)請求的層绳慎。
    我同樣所有的Model都放在IModel類里面纵竖,IModel文件里的一個接口就對應著一個Model模塊的網(wǎng)絡請求方法,方便對醒目里的所有網(wǎng)絡請求進行管理杏愤。
    很明顯靡砌,登錄模塊的Model就只有一個請求登錄的方法,對于通知Presenter層數(shù)據(jù)更新完畢珊楼,則是通過接口回調(diào)的方式通殃。
public class IModel {

    /**
     * 登錄
     */
    public interface ILoginModel {
        void login(LoginBody loginBody, MyCallBack<UserLoginBean> callBack); //登錄
    }

}

通過接口回調(diào)通知Presenter數(shù)據(jù)已更新完畢。

public interface MyCallBack<T> {
    void onSuccess(T response);         //成功回調(diào)
    void onError(String header,String message);   //失敗回調(diào)
    void onDispose(Disposable disposable);   // 切斷上有發(fā)送事件
}

對于登錄模塊亥曹,要有登錄模塊的Model繼承自IModel里對應的接口邓了。

public class LoginModel implements IModel.ILoginModel {

    /**
     * 構(gòu)造方法
     *
     * @param
     */
    @Override
    public void login(LoginBody loginBody, final MyCallBack<UserLoginBean> callBack) {
        JsNetworkService.getInstance().getIJsNetworkService()
                .getLogin(loginBody)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<UserLoginBean>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Disposable mDisposable; //用于Activity銷毀時停止執(zhí)行
                        mDisposable = d;
                        callBack.onDispose(mDisposable);
                    }

                    @Override
                    public void onNext(@NonNull UserLoginBean userLoginBean) {
                        callBack.onSuccess(userLoginBean);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        callBack.onError("Server Error", "服務器異常,請稍后再試");
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}
3.Presenter

Presenter層的作用:

  • 操作Model進行數(shù)據(jù)更新
  • 操作View層進行界面更新
    Presenter層實際起到的是個類似的中介作用媳瞪,所以在Presenter層里有對View和Model的引用骗炉。
public class LoginPresenter {

    private IView.ILoginView mILoginView;
    private LoginModel mLoginModel;

    public LoginPresenter(IView.ILoginView iLoginView) {
        this.mILoginView = iLoginView;
        mLoginModel = new LoginModel();
    }

    /**
     * 登錄
     */
    public void login() {
        mILoginView.showProgress();
        LoginBody loginBody = new LoginBody(mILoginView.getPassWord(), mILoginView.getUserName());

        mLoginModel.login(loginBody, new MyCallBack<UserLoginBean>() {
            @Override
            public void onSuccess(UserLoginBean userLoginBean) {
                mILoginView.hideProgress();
                if (userLoginBean.getStatus().equals("1")) {
                    mILoginView.toOtherActivity();
                }
                mILoginView.showToast(userLoginBean.getMessage());


            }

            @Override
            public void onError(String header, String message) {
                mILoginView.hideProgress();
                mILoginView.showToast(message);
            }

            @Override
            public void onDispose(Disposable disposable) {
                mILoginView.closeDispose(disposable);
            }
        });


      /*  mLoginModel.login(loginBody, new MyCallBack.OnLoginListener() {
            @Override
            public void loginSuccess(UserLoginBean userLoginBean) {
                mILoginView.showToast(userLoginBean.getMessage());
            }

            @Override
            public void loginFailed(String header, String message) {

            }

            @Override
            public void dispose(Disposable disposable) {
                mILoginView.closeDispose(disposable);
            }
        });*/

    }
}

然后再Activity里,通過下面的代碼引入

 LoginPresenter mLoginPresenter = new LoginPresenter(this);

通過 mLoginPresenter.login()在Activity里執(zhí)行登錄方法蛇受。

上面mvp模式時沒有引進Dagger2的時候句葵,下面引進Dagger2。

1.首次分析一下需要Inject哪個對象兢仰。

  • 在Activity里持有了一個LoginPresenter 對象的引用乍丈,傳入的是一個IView.ILoginView,通過IView.ILoginView把将,LoginPresenter 實現(xiàn)從Activity接接受請求轻专,請求成功后通知Activity更新界面。所以這個LoginPresenter 可以通過Inject的形式注入察蹲。
LoginPresenter mLoginPresenter = new LoginPresenter(this);
  • 在LoginPresenter里请垛,構(gòu)造方法里有個LoginModel對象,所以也是可以注入的洽议。
public LoginPresenter(IView.ILoginView iLoginView) {
        this.mILoginView = iLoginView;
        mLoginModel = new LoginModel();
    }

所以LoginActivity里修改代碼如下:

 @Inject
    LoginPresenter mLoginPresenter;

LoginPresenter里修改代碼如下:

 @Inject
    LoginModel mLoginModel;

2. Module

前文說過宗收,Module是提供依賴的,要提供@Provides注解的以provide開頭的方法亚兄。
上面說過混稽,我們需要提供的是LoginPresenter和LoginModel的對象。
但是在提供LoginPresenter對象的時候,發(fā)現(xiàn)它需要一個IView.ILoginView的對象匈勋,所以我們還要用過IView.ILoginView的對象礼旅。
所以這里我們要提供三個依賴。
在這里補充一下當遇到@Inject注解的時候處理步驟:

1. 查找Module中是否有創(chuàng)建該類的方法
2. 若存在創(chuàng)建該類的方法颓影,查看該方法是否有參數(shù)
    2.1 有參數(shù)各淀,實例化該類,并且從  步驟1  開始初始化每個參數(shù)
    2.2  沒有參數(shù)诡挂,直接實例化該類碎浇,一次注入完成
3. 不存在創(chuàng)建該類的方法,查找Inject注解的構(gòu)造函數(shù)璃俗,看構(gòu)造函數(shù)是否存在參數(shù)
    3.1:若存在參數(shù)奴璃,則  步驟1   開始依次初始化每個參數(shù)
    3.2:若不存在參數(shù),則直接初始化該類實例城豁,一次依賴注入完成0

所以Module的代碼為

@Module
public class LoginModule {

    private IView.ILoginView loginView;

    public LoginModule(){

    }

    public  LoginModule(IView.ILoginView view){
        this.loginView=view;
    }

    /**
     * 提供LoginPresenter
     * @param iLoginView
     * @return
     */
    @Provides
    @Singleton
    LoginPresenter provideLoginPresenter(IView.ILoginView iLoginView){
        return new LoginPresenter(iLoginView);
    }

    @Provides
    @Singleton
    IView.ILoginView provideILoginView(){
        return loginView;
    }

    @Provides
    @Singleton
    LoginModel provideLoginModel(){
        return new LoginModel();
    }

}

這里提一下苟穆,LoginModule有兩個構(gòu)造方法,因為注入到Activity是需要參數(shù)的唱星,而注入到LoginPresenter是不需要參數(shù)的雳旅。

3.Component

Component 是聯(lián)系inject和Module的橋梁,習慣稱為注入器

@Singleton
@Component(modules = {LoginModule.class})
public interface LoginComponent {

    void inject(LoginActivity loginActivity);
    void inject(LoginPresenter loginPresenter);

}

4.執(zhí)行注入

在Activity里添加代碼

 DaggerLoginComponent.builder()
                .loginModule(new LoginModule(this))
                .build()
                .inject(this);

在LoginPresenter里添加代碼

 DaggerLoginComponent.builder()
                .loginModule(new LoginModule())
                .build()
                .inject(this);

編譯執(zhí)行间聊,即可看到效果


源碼傳送門

目前我們接觸到的Dagger2的注解符攒盈,有@Inject @Module @Provide @Component等,其實Dagger2還有其他的注解符哎榴,比如 @Singleton(其實前面代碼有了)型豁,@Scope @Qualifier等,下一篇文章簡要介紹一下尚蝌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末迎变,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子飘言,更是在濱河造成了極大的恐慌衣形,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姿鸿,死亡現(xiàn)場離奇詭異谆吴,居然都是意外死亡,警方通過查閱死者的電腦和手機般妙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來相速,“玉大人碟渺,你說我怎么就攤上這事。” “怎么了苫拍?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵芜繁,是天一觀的道長。 經(jīng)常有香客問我绒极,道長骏令,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任垄提,我火速辦了婚禮榔袋,結(jié)果婚禮上婆芦,老公的妹妹穿的比我還像新娘浑测。我一直安慰自己腰奋,他們只是感情好兑燥,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布渣锦。 她就那樣靜靜地躺著霍狰,像睡著了一般推正。 火紅的嫁衣襯著肌膚如雪训柴。 梳的紋絲不亂的頭發(fā)上滩报,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天锅知,我揣著相機與錄音,去河邊找鬼脓钾。 笑死售睹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的惭笑。 我是一名探鬼主播侣姆,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沉噩!你這毒婦竟也來了捺宗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤川蒙,失蹤者是張志新(化名)和其女友劉穎蚜厉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畜眨,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡昼牛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了康聂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贰健。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖恬汁,靈堂內(nèi)的尸體忽然破棺而出伶椿,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布脊另,位于F島的核電站导狡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏偎痛。R本人自食惡果不足惜旱捧,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踩麦。 院中可真熱鬧枚赡,春花似錦、人聲如沸靖榕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茁计。三九已至料皇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間星压,已是汗流浹背践剂。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留娜膘,地道東北人逊脯。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像竣贪,于是被迫代替她去往敵國和親军洼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

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