Android官方架构分析(一)——todo‑mvp

作者: 管弦_ | 来源:发表于2017-08-02 19:59 被阅读363次

    前言

    android-architecture是google官方推出的关于Android架构设计的开源项目,相当于为开发者提供了在Android APP架构设计方面的指南,所以学习价值不言而喻。

    该项目展示了多种不同的架构概念和工具来实现相同的应用程序,这里我们将挑选其中一些经典的架构方式对其Demo进行源码分析。

    这一篇,我们对标准MVP架构的todo‑mvp进行分析。

    项目结构

    android-architecture一系列Demo都实现了一个TODO-LIST项目,分为任务列表(tasks)、任务详情(taskdetail)、添加任务(addedittask)、任务统计(statistics)四个功能模块。

    从下图分包情况也可以看出,todo‑mvp项目是按功能模块划分包名,清晰易懂。

    imageimage
    • addedittask:添加任务
    • data:主要对数据来源实现了封装
    • statistics:任务统计
    • taskdetail:任务详情
    • tasks:任务列表
    • util:帮助类
    • BasePresenter:Presenter基类
    • BaseView:View基类

    架构思路

    标准MVP架构有别于Android传统MVC架构最明显的地方在于,View与Model不发生联系,通过Presenter传递。而View不再承担逻辑功能,只负责显示视图页面,逻辑由Presenter进行处理。

    imageimage

    在todo‑mvp项目中,每一个具体模块都由Model、Presenter、View三部分来实现。

    • Model:data包内的数据来源的封装实现类,分为本地来源和远程来源。
    • Presenter:由Activity创建Presenter实例对象。
    • View:由Activity创建,并由Fragment作为View的具体实现。
    imageimage

    上图为官方给出的结构图,清晰的展示了MVP各部分的具体实现。

    代码分析

    在MVP模式中,每一个功能模块都由Model、Presenter、View组成,我们用addedittask模块来展示代码。

    imageimage

    AddEditTaskContract类:

    /**
     * This specifies the contract between the view and the presenter.
     */
    public interface AddEditTaskContract {
    
        interface View extends BaseView<Presenter> {
    
            void showEmptyTaskError();
    
            void showTasksList();
    
            void setTitle(String title);
    
            void setDescription(String description);
    
            boolean isActive();
        }
    
        interface Presenter extends BasePresenter {
    
            void saveTask(String title, String description);
    
            void populateTask();
    
            boolean isDataMissing();
        }
    }
    

    Contract类作为View和presenter之间的协议,封装了View和Presenter接口。MVP模式下,分出View接口和Persenter接口主要是为了将View和Persenter通过接口的方式解耦,而Contract将两者封装到一起,又可以方便查找和修改。

    View接口中封装了对页面展示绘制渲染等相关操作,Persenter接口中封装了对程序逻辑、对接Model等相关操作。View接口和Presenter接口又分别继承了BaseView和BasePresenter。

    public interface BaseView<T> {
    
        void setPresenter(T presenter);
    
    }
    

    BaseView中需要保持对Presenter的引用。

    public interface BasePresenter {
    
        void start();
    
    }
    

    BasePresenter中的start方法主要用于一些初始化操作。

    AddEditTaskActivity类中创建AddEditTaskPresenter实例:

        // Create the presenter
        mAddEditTaskPresenter = new AddEditTaskPresenter(
                taskId,
                Injection.provideTasksRepository(getApplicationContext()),
                addEditTaskFragment,
                shouldLoadDataFromRepo);
    

    Activity在MVC模式下,需要承担View和Controller两者的职责,代码相当繁重。而在MVP模式下,不再承担过多的功能。创建Presenter时传入Model和View的实例,具体逻辑操作都由Presenter来负责。

    Presenter

    public class AddEditTaskPresenter implements AddEditTaskContract.Presenter,
            TasksDataSource.GetTaskCallback {
            
        @NonNull
        private final TasksDataSource mTasksRepository;
    
        @NonNull
        private final AddEditTaskContract.View mAddTaskView;
    
        @Nullable
        private String mTaskId;
    
        private boolean mIsDataMissing;
    
        /**
         * Creates a presenter for the add/edit view.
         *
         * @param taskId ID of the task to edit or null for a new task
         * @param tasksRepository a repository of data for tasks
         * @param addTaskView the add/edit view
         * @param shouldLoadDataFromRepo whether data needs to be loaded or not (for config changes)
         */
        public AddEditTaskPresenter(@Nullable String taskId, @NonNull TasksDataSource tasksRepository,
                @NonNull AddEditTaskContract.View addTaskView, boolean shouldLoadDataFromRepo) {
            mTaskId = taskId;
            mTasksRepository = checkNotNull(tasksRepository);
            mAddTaskView = checkNotNull(addTaskView);
            mIsDataMissing = shouldLoadDataFromRepo;
    
            mAddTaskView.setPresenter(this);    //将Presenter实例对象赋给View
        }
    
        @Override
        public void start() {
            if (!isNewTask() && mIsDataMissing) {
                populateTask();
            }
        }
            
        ...
        
    }
    

    AddEditTaskPresenter实现了AddEditTaskContract.Presenter接口,并在构造函数中获取了Model和View的实例,具体业务逻辑就是对这两个实例对象进行操作来实现。

    mTasksRepository:相当于Model的实例对象,对数据操作的具体实现。

    mAddTaskView:相当于View的实例对象,页面展示的具体实现。

    start()方法中执行了对Model对象(mTasksRepository)赋值和初始化工作。

    View

    public class AddEditTaskFragment extends Fragment implements AddEditTaskContract.View {
    
        private AddEditTaskContract.Presenter mPresenter;
        
        @Override
        public void onResume() {
            super.onResume();
            mPresenter.start();
        }
    
        @Override
        public void setPresenter(@NonNull AddEditTaskContract.Presenter presenter) {
            mPresenter = checkNotNull(presenter);
        }
        
        ...
        
    }
    

    AddEditTaskFragment实现了AddEditTaskContract.View接口,通过setPresenter方法获得Presenter实例,在onResume方法中执行Presenter的初始化操作,而当View接收到触发事件时,由Presenter实例来负责响应逻辑。

    Model

    public class TasksRepository implements TasksDataSource {
    
        private static TasksRepository INSTANCE = null;
    
        private final TasksDataSource mTasksRemoteDataSource;
    
        private final TasksDataSource mTasksLocalDataSource;
    
        // Prevent direct instantiation.
        private TasksRepository(@NonNull TasksDataSource tasksRemoteDataSource,
                                @NonNull TasksDataSource tasksLocalDataSource) {
            mTasksRemoteDataSource = checkNotNull(tasksRemoteDataSource);
            mTasksLocalDataSource = checkNotNull(tasksLocalDataSource);
        }
        
        ...
        
    }
    

    TasksRepository作为Model层的实现类,实现了TasksDataSource接口,封装了本地数据和远程数据两种数据来源,通过TasksRepository实例对象可对数据接口做统一操作。

    总结

    MVP架构较之以前的MVC架构,在代码模块解耦方面表现更出色,并且解决了Activity责任繁杂的问题。

    • View:只负责显示、绘制、渲染等工作。
    • Model:负责数据操作,如数据库、网络数据、缓存等。
    • Presenter:作为View和Model的桥梁,并负责程序逻辑。

    这篇博客是Android架构一系列博客的第一篇,而且是比较标准的MVP架构,看起来有些老调重弹。后续将逐步分析android-architecture中一些比较成熟的架构,并分析与标准MVP架构的优劣。

    相关文章

      网友评论

      本文标题:Android官方架构分析(一)——todo‑mvp

      本文链接:https://www.haomeiwen.com/subject/nzvylxtx.html