详细的Dagger2+MVP融合,一行一行分析,一点一点进步,之二

    上一篇我们大致了解了项目的结构组成,这一篇我们来分别说说里面的细节。


    首先,搭建框架,就要根据框架的特点去完成初步的搭建。根据MVP的官网描述,我们首先完成MVP框架的基础构建,每一个activity都是一个V,一个V对应一个Presenter,所以在每一个界面的包下面,就至少包含了三个文件,IXXXConstane(V、P接口描述类)、XXXActivity(V)、XXXPresenter(P),每一个类的职责也必须清晰,XXXActivity主要用来作显示界面使用,不能包含任何逻辑,XXXPresenter主要用来沟通数据模块和V,数据改变了,就应该通知相应的界面控件进行改变,这是MVP框架中很重要的思想,每一个模块都只是完成自己的功能,不能逾越。


    来看代码,在每一个V中都持有P的引用,那么在V中是可以调用P中的逻辑的,但我们一般不这么做,在V中持有P的引用,我们只是为了初始化P,让P和V关联起来,而不是直接去调用P中的逻辑,这点比较重要,不然结构就比较混乱了。比如在MainActivity中,就持有IMainConstane.IMainPresenter的引用,但我们一般不直接调用IMainPresenter中的逻辑:

public class MainActivity extends BaseActivity implements IMainConstane.IMainView {

    @Inject
    IMainConstane.IMainPresenter mMainPresenter;

    private TextView tv;

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

        tv = (TextView) findViewById(R.id.text);

        DaggerMainComponent.builder()
                .userModelComponent(((MyApplication) getApplicationContext()).getUserModelComponent())
                .mainModule(new MainModule(this))
                .build()
                .inject(this);
    }

    public void onViewClick(View view) {
        switch (view.getId()) {
            case R.id.login:
                // 这里打印一下用户模块对象的地址,来判断@Singleton单利模式是否有用
                mMainPresenter.logUserHashcode();
                mMainPresenter.login("", "");
                break;
            case R.id.view_detail:
                startActivity(new Intent(getApplicationContext(), SecondActivity.class));
                break;
        }
    }

    @Override
    public void setTextMessage(String message) {
        if (TextUtils.isEmpty(message)) {
            tv.setText("");
        } else {
            tv.setText(message);
        }
    }
}

    可以看到,我在V中,是没有直接调用P中的逻辑代码的,但有一种情况例外,就是事件交互,在人机进行交互的过程中,我们需要进行一些数据的操作,这个时候直接调用是没问题的。

    我所说的只是“最好不要在V中直接调用P的代码,并不是一定不能,V中调用P的代码会显得结构层次有点乱,但如果业务需要,那也没办法


    看完V,我们再来说说P,P的构造函数中就传递进来两个参数,分别为M和V,这也就是为什么P是整个框架的逻辑处理核心的原因了,因为同时持有两者,那么就可以使用两者暴露出来的接口进行整个逻辑的操作和判断了。

public class MainPresenter implements IMainConstane.IMainPresenter {

    private final IMainConstane.IMainView mView;

    private final IUserModel mUserModel;

    public MainPresenter(IMainConstane.IMainView view, IUserModel usermodel) {
        this.mView = view;
        this.mUserModel = usermodel;
    }

    @Override
    public void login(String userName, String password) {
        mUserModel.login(userName, password, new OnLoginListener() {
            @Override
            public void loginSuccess() {
                mView.setTextMessage("login Success");
            }

            @Override
            public void loginFaile(String message) {
                mView.setTextMessage("login Faile");
            }
        });
    }

    @Override
    public void logUserHashcode() {
        mUserModel.logUser();
        mUserModel.logOkHttp();
        mUserModel.logRetrofit();
    }
}

    看上面的代码,当界面点击之后,会调用P中的login方法,也就是上面的login方法了,而该方法中则调用的是数据模块中的登录方法,我们跟进去看一下,就会发现调用到了UserModelImpl里面的登录方法,这样,整个逻辑就很清楚了,界面发起数据请求,通过P转到数据层,数据层通过回调接口(OnLoginListener)回调给P,然后P再根据持有的V进行界面的更改,也就是

mView.setTextMessage("login Success");
和
mView.setTextMessage("login Faile");


    其实在这里是有一个歧义和区别的,你可能注意到了model包下的otherModel,它代表的是你项目中除用户数据模块之外的其它数据模块,比如我应用里面还需要产品数据模块,那么在P中如何将这些数据模块传递进去呢?


    总不能修改P的构造函数,将所有数据模块依次传递进去吧?这样做先不说修改构造函数有多么繁琐,就算有dagger2我也不推荐这样使用。

    我觉得,数据模块因该统一一个入口,然后里面应该分别持有所需模块,然后将统一入口提供给P。当然,这只是我想的,每个人对这个地方的处理可能不一样,有些人喜欢分别传入,也有些人喜欢统一入口方便管理,这就看个人喜好了!


    最好还想看一下数据模块的组成的,但看了一下,觉得没什么好说的,代码写的很详细也简单易懂,主要就是接口编程,一个接口类IUserModel,一个实现类UserModelImpl。


    这个地方不明白的可以私聊我!



源码下载

详细的Dagger2+MVP融合,一行一行分析,一点一点进步,之一

详细的Dagger2+MVP融合,一行一行分析,一点一点进步,之三

详细的Dagger2+MVP融合,一行一行分析,一点一点进步,之四

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值