android进阶Android开发经验谈Android技术知识

Android开发之Dagger2--MVP模式中使用(四)

2018-03-28  本文已影响946人  Jackson杰

前言

在上一篇文章里Android开发之Dagger2--Module&Component(三),主要分析了Dagger2注入过程,Module和Component各有什么作用,使用的例子也是很简单的。前面曾经提到过,Dagger2最适合在mvp模式中使用,那这位篇文章就是应用在mvp模式中。对mvp模式不了解的可以参照 Android架构--MVC、MVP、MVVMMVP模式--登录,这一篇文章就是在第二篇文章的基础上引入了Dager2。

废话不说,直接上代码 源码传送门

代码

1 .View

mvp模式的view部分,我把它放在一个接口里面,当然可以单独为登录模块写一个View接口,考虑到每个界面有可能都会有个View接口,所以我把它们放在一个IView接口里,这样可以减少接口文件的数量。
view的主要作用是
1.接收用户请求,并把请求传递给Presenter层处理。
2.Presenter操作View层更新数据

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模块实现的,不同于在传统的MVC模式,在MVC模式里,Activity既是View层,又是Model层,在MVP里,Activity则完全充当了View的角色。
所以在要Activity里实现ILoginView 接口。

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

Model层的作用如下:

public class IModel {

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

}

通过接口回调通知Presenter数据已更新完毕。

public interface MyCallBack<T> {
    void onSuccess(T response);         //成功回调
    void onError(String header,String message);   //失败回调
    void onDispose(Disposable disposable);   // 切断上有发送事件
}

对于登录模块,要有登录模块的Model继承自IModel里对应的接口。

public class LoginModel implements IModel.ILoginModel {

    /**
     * 构造方法
     *
     * @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销毁时停止执行
                        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层的作用:

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里执行登录方法。

上面mvp模式时没有引进Dagger2的时候,下面引进Dagger2。

1.首次分析一下需要Inject哪个对象。

LoginPresenter mLoginPresenter = new LoginPresenter(this);
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对象的时候,发现它需要一个IView.ILoginView的对象,所以我们还要用过IView.ILoginView的对象。
所以这里我们要提供三个依赖。
在这里补充一下当遇到@Inject注解的时候处理步骤:

1. 查找Module中是否有创建该类的方法
2. 若存在创建该类的方法,查看该方法是否有参数
    2.1 有参数,实例化该类,并且从  步骤1  开始初始化每个参数
    2.2  没有参数,直接实例化该类,一次注入完成
3. 不存在创建该类的方法,查找Inject注解的构造函数,看构造函数是否存在参数
    3.1:若存在参数,则  步骤1   开始依次初始化每个参数
    3.2:若不存在参数,则直接初始化该类实例,一次依赖注入完成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有两个构造方法,因为注入到Activity是需要参数的,而注入到LoginPresenter是不需要参数的。

3.Component

Component 是联系inject和Module的桥梁,习惯称为注入器

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

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

}

4.执行注入

在Activity里添加代码

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

在LoginPresenter里添加代码

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

编译执行,即可看到效果


源码传送门

目前我们接触到的Dagger2的注解符,有@Inject @Module @Provide @Component等,其实Dagger2还有其他的注解符,比如 @Singleton(其实前面代码有了),@Scope @Qualifier等,下一篇文章简要介绍一下。

上一篇下一篇

猜你喜欢

热点阅读