Android Google MVP Demo TODO解读

今天周六抽时间把google的2个 MVP Demo看一下,写篇文章记录一下.

 先来看一下第一个最基础的todo-mvp

下图是Google MNP第一个Demo的架构图,至于为什么要使用Activity+Fragment,这里是把Activity当做了控制器(Controllers),负责创建Frament和Presenter并连接他们。Activity和Repository之间的圆圈代表他们直接主要通过接口交互。



下面看源码

 可以看出是每一个界面都单独在一个包里面,Model层作为公共的模块在data包下



BasePresenter中需要定义一些所有Presenter的基础行为,Demo中定义一个start方法



BaseView定义了设置Presenter的方法,每个View都需要有一个对应的Presenter.



每个Fragment都会有一个契约类,用来定义具体的BaseView和Presenter接口,从这个契约类能后一眼看出Presenter和UI有什么操作,比如TaskDetailContract中

interface View extends BaseView<Presenter> {

    void setLoadingIndicator(boolean active);

    void showMissingTask();

    void hideTitle();

    void showTitle(String title);

    void hideDescription();

    void showDescription(String description);

    void showCompletionStatus(boolean complete);

    void showEditTask(String taskId);

    void showTaskDeleted();

    void showTaskMarkedComplete();

    void showTaskMarkedActive();

    boolean isActive();
}

interface Presenter extends BasePresenter {

    void editTask();//编辑task

    void deleteTask();

    void completeTask();

    void activateTask();
}复制代码


 下面进入TaskDetailActivity 看一下

以下是OnCreate的代码片段,UI的就省略了,创建了Fragment并添加到Activity

   ActivityUtils.addFragmentToActivity(getSupportFragmentManager(),
            taskDetailFragment, R.id.contentFrame);
}

// Create the presenter
new TaskDetailPresenter(
        taskId,
        Injection.provideTasksRepository(getApplicationContext()),
        taskDetailFragment);复制代码

并且new了一个Presenter,把fragment和repository传入presenter中,来看一下在TaskDetailPresenter里做了什么

public TaskDetailPresenter(@Nullable String taskId,
                           @NonNull TasksRepository tasksRepository,
                           @NonNull TaskDetailContract.View taskDetailView) {
    mTaskId = taskId;
    mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null!");
    mTaskDetailView = checkNotNull(taskDetailView, "taskDetailView cannot be null!");

    mTaskDetailView.setPresenter(this);
}复制代码

    mTaskDetailView.setPresenter(this);很关键,将TaskDetailPresenter的引用传给了fragment,并保存了对应的view(taskDetailView),这样V 和 P就相互保存了对方的实例。


 mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null!");
复制代码

  可以看到TaskDetailPresenter还保存了Model层的一个引用mTasksRepository,如果需要去获取一个Task就是利用mTasksRepository.getTask(int id);

   mTasksRepository从哪来的??其实在我们new presenter的时候构造并传入的

// Create the presenter
new TaskDetailPresenter(
        taskId,
        Injection.provideTasksRepository(getApplicationContext()),
        taskDetailFragment);复制代码

  public static TasksRepository provideTasksRepository(@NonNull Context context) {

    checkNotNull(context);
    ToDoDatabase database = ToDoDatabase.getInstance(context);
    return TasksRepository.getInstance(FakeTasksRemoteDataSource.getInstance(),
            TasksLocalDataSource.getInstance(new AppExecutors(),
                    database.taskDao()));
}复制代码

  在构造TaskRepository的时候传入了FakeTasksRemoteDataSource和TasksLocalDataSource的单例,,这2个都是提供数据的,都实现了getTask(int id)方法,分别从远程和本地获取,在TasksRepository中会根据情况来进行调用,如果本地数据源获取不到就从远端数据源获取

@Override
public void getTask(@NonNull final String taskId, @NonNull final GetTaskCallback callback) {
    //从本地数据库获取
    mTasksLocalDataSource.getTask(taskId, new GetTaskCallback() {
        @Override
        public void onTaskLoaded(Task task) {
            // Do in memory cache update to keep the app UI up to date
         
            mCachedTasks.put(task.getId(), task);
            callback.onTaskLoaded(task);
        }

        @Override
        public void onDataNotAvailable() {
            //从远端获取
            mTasksRemoteDataSource.getTask(taskId, new GetTaskCallback() {
                @Override
                public void onTaskLoaded(Task task) {
                 
                    mCachedTasks.put(task.getId(), task);
                    callback.onTaskLoaded(task);
                }

                @Override
                public void onDataNotAvailable() {
                    callback.onDataNotAvailable();
                }
            });
        }
    });
}复制代码

获取到数据之后便通过callback回到给presenter,然后在回调里调用View接口进行UI的显示。


mTasksRepository.getTask(mTaskId, new TasksDataSource.GetTaskCallback() {
    @Override
    public void onTaskLoaded(Task task) {
        
            showTask(task);
     
    }复制代码


整个流程基本是这样,来看一下时序图

    总结一下,首先Activity负责管理管理View和Presenter以及他们的连接,以及创建Model,让Model和Presenter互相持有对方的引用,TaskRepository则负责数据源的管理以及怎么获取,是否从缓存中获取还是本地数据库或者远端服务器,相对于传统的开发模式,Presenter极大的减轻了Activity的负担,让Activity只关注UI方面的显示。

     代码虽然简单,但是真正用在项目中我感觉不会这么简单,第一点疑问就是这么一个demo工程就需要创建这么多class,这样的话在大项目中那会有多少class!

     Google提供的Demo只是一个样本,实际使用中肯定要结合项目进行灵活架构调整


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值