The--MVP of Android's common architecture

Source: Internet
Author: User

Overview

The MVP (Model View Presenter) architecture evolved from the well-known MVC (Model View Controller) architecture. For Android applications, the development itself can be seen as an MVC architecture. The XML file is typically considered a view role in MVC in development, while activity is considered a controller role in MVC. However, in many cases, the activity can not fully act as a controller in practical application development, but a combination of controller and view. The activity is responsible for the display of the view and the handling of the business logic. This allows the code to reach thousands of lines in the activity, or even thousands of of rows are not enough, and the activity looks bloated. Therefore, the MVC architecture is not very suitable for Android development. Here's an introduction to the MVP architecture and a look at Google's official example of the MVP architecture.

Introduction to the MVP architecture

For an application we need to abstract all facets of it, and in the MVP architecture it isolates the UI interface and data, so our application is divided into three levels.

    • View: It is also the views layer, which is only responsible for the presentation of the data and provides a friendly interface to interact with the user. Activity or fragment is often used as the view layer in Android development.
    • Model: For the model layer is also the data layer. It is different from the model in the MVC architecture, where it is more than just the data models. In the MVP architecture, the model is responsible for accessing data, such as reading and writing the database, requests for data from the network, and so on.
    • Presenter: For Presenter layer He is the bridge between the view layer and the model layer and processes the business logic. Model and view cannot interact directly in the MVP architecture. So in the presenter layer it will get the required data from the model layer and do some proper processing to show it to the view layer. This isolates the view from the model by presenter so that there is no coupling between the view and the model, and the business logic is drawn away from view.

      Here's a look at the relationship between the various levels of the MVP through the MVP chart.

      In the MVP architecture, these three layers are abstracted separately into their respective interfaces. The interfaces are used to isolate the layers, and the presenter of the view and model depend on their respective interfaces. This conforms to the principle of interface isolation, and it is interface-oriented programming. A view interface is included in the presenter layer and is dependent on the model interface to associate the model layer with the view layer. For the view layer, a Presenter member variable is held and only the calls to the presenter interface are retained, and the specific business logic is all handled by the presenter interface implementation class.

Official MVP Architecture Analysis Project Introduction

There is some understanding of the MVP architecture, and at the front-end time Google gives some implementation of the app development architecture.
The project address is: Https://github.com/googlesamples/android-architecture.
Go to the readme here to see what Google has to offer for Android development architectures.


The implementation of the above five development architectures represents the projects that have been completed so far, while the following two represent projects in progress. Now let's start by introducing these architectures.

    • TODO-MVP: the base MVP architecture.
    • Todo-mvp-loaders: Based on the implementation of the MVP architecture, the loaders architecture is used in the Data acquisition section.
    • Todo-mvp-databinding: Based on the implementation of the MVP architecture, data binding components are used.
    • Todo-mvp-clean: The implementation of the clean architecture based on the MVP architecture.
    • Todo-mvp-dagger2: Based on the MVP architecture, the dependency injection dagger2 is used.
    • Dev-todo-mvp-contentproviders: Based on the mvp-loaders architecture, Contenpproviders is used.
    • Dev-todo-mvp-rxjava: An abstraction based on the MVP architecture for concurrent processing of programs and data layers (model in MVP).

      As you can see from the above introduction, the implementation of all the architectures given by the authorities is ultimately based on the MVP architecture. So here's an analysis of the above based MVP architecture TODO-MVP.

      analysis of the project structure

      For this project, it implements the function of a memo. Added to the to-do list for unfinished tasks in the work. We are able to mark completed tasks in the list, to be able to modify the task content on the task Detail page, and to count the completed tasks and the number of unfinished tasks.
      First, here's a look at the overall project structure of TODO-MVP.

      As you can see, the overall project contains an app src directory, four test directories. In the SRC directory, the way the code is organized is broken down by function. There are four features in this project, namely: Add edits to Tasks (addedittask), Task completion statistics (statistics), Task Details (taskdetail), Task List display (tasks). For the data packet, it is the source of the project, the database reads and writes, the network request operation is stored in the package, is also the model layer in the MVP schema. The Util package below is a tool class for storing some of the items used in the project. Two interfaces Basepresenter and Baseview are stored at the outermost layer. They are the base class for the presenter layer interface and the view layer interface, and all the presenter and view layer interfaces in the project inherit from both interfaces.
      Now go into the function module and see how the class is divided within the module. The classes are divided into xxactivity,xxfragment,xxpresenter,xxcontract under each function module. It is these classes that make up the presenter layer and the view layer in the project. The following is an analysis of how the MVP architecture is implemented in this project.

      the implementation of the MVP architecture

      This is only a macro focus on the implementation of the MVP architecture, the internal details of the code is not in the specific analysis. Then take the task of adding and editing this feature to see how the official Android implementation of the MVP architecture.

      implementation of the model layer

      First we start with an analysis of the most inner layers of the MVP architecture, which is the corresponding model layer. The contents of the corresponding data package in this project. The encapsulation of some data sources, such as databases, under data. The Tasksdatasource interface is provided for the presenter layer. Take a look at this Tasksdatasource interface here.

    • public interface Tasksdatasource {interface Loadtaskscallback {void O        Ntasksloaded (list<task> tasks);    void Ondatanotavailable ();        } interface Gettaskcallback {void ontaskloaded (task Task);    void Ondatanotavailable ();    } void Gettasks (@NonNull loadtaskscallback callback);    void Gettask (@NonNull String taskId, @NonNull Gettaskcallback callback);    void Savetask (@NonNull task Task); ......}
      The implementation of the

      Tasksdatasource interface is Taskslocaldatasource, and the method in Tasksdatasource is the operation of some additions and deletions to the database. In Tasksdatasource, the two internal interfaces Loadtaskscallback and Gettaskcallback are the callback interfaces of the model layer. Their true realization is in the presenter layer. The data is passed to the presenter layer after the data has been successfully acquired or transmitted through this callback interface. Similarly, if the acquisition fails, the presenter layer is also notified through the callback interface. Here's a look at the implementation class for Tasksdatasource.

    • public class Taskslocaldatasource implements Tasksdatasource {    ...    @Override public    void Gettask (@NonNull String taskId, @NonNull Gettaskcallback callback) {        // According to TaskID to find out the corresponding task        ...        if (task! = null) {            callback.ontaskloaded (Task);        } else {            callback.ondatanotavailable ();}    }    @Override public    void Savetask (@NonNull task Task) {        checknotnull (Task);        Sqlitedatabase db = Mdbhelper.getwritabledatabase ();        Contentvalues values = new Contentvalues ();        Values.put (taskentry.column_name_entry_id, Task.getid ());        Values.put (Taskentry.column_name_title, Task.gettitle ());        Values.put (Taskentry.column_name_description, Task.getdescription ());        Values.put (taskentry.column_name_completed, task.iscompleted ());        Db.insert (taskentry.table_name, null, values);        Db.close ();    }    ......}

        

      Here we are adding and editing functions for tasks, so we omit a lot of code. You can see the Gettask method implemented in Taskslocaldatasource, in which the Gettaskcallback callback interface within the Tasksdatasource is passed in. The implementation of the Gettask method shows that the callback method is called after the query to the task, and if the two callback methods are implemented in the presenter layer, the data is passed to the presenter layer. A callback method is also used to perform the corresponding operation for a query to a task that is empty.
      The same is true for data obtained through a network request, the data that is successfully requested can be passed to the presenter layer through the callback method, and the corresponding operation can be performed by the callback method for network request failure.

      interfaces provided by the presenter and view layers

      Since the interfaces provided in the presenter and view layers are in a class, here is a first look at what interfaces they provide to the outside. First, look at the two base class interfaces Basepresenter and Baseview.

      Basepresenter

    • Package Com.example.android.architecture.blueprints.todoapp;public interface Basepresenter {    void Start ();}

        

      There is only one start method in Basepresenter. This method typically performs the task of fetching data from the model layer in presenter and invoking the view interface display. This method is typically called in the Onresume method in fragment.

      Baseview

    • package com.example.android.architecture.blueprints.todoapp;public Interface baseview<t> {void Setpresenter (T presenter);} 

      There is only one Setpresenter method in Baseview, and there is a presenter object for the view layer. And Setpresenter is the presenter in the view is initialized.

      addedittaskcontract

      In the MVP architecture given by Android, the presenter interface and the view interface are available in a different form than we normally see on the web. Here the interface between presenter and view is placed in the Addedittaskcontract class. This allows us to see more clearly what functions are available in the presenter Layer and view layer, which facilitates our future maintenance. Here's a look at this addedittaskcontract class.

    • 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 CreateTask (string title, string description);        void Updatetask (string title, string description);    void Populatetask (); The 

      is clearly visible here in the view layer that handles some data display operations, while in the presenter layer, the task is saved, updated, and so on. The implementation of the

      presenter Layer

      Looks at how presenter is implemented.

    • public class Addedittaskpresenter implements Addedittaskcontract.presenter, Tasksdatasource.gettaskcallback {..  Public Addedittaskpresenter (@Nullable String taskId, @NonNull tasksdatasource tasksrepository, @NonNull        Addedittaskcontract.view addtaskview) {mtaskid = TaskId;        Mtasksrepository = Checknotnull (tasksrepository);        Maddtaskview = Checknotnull (Addtaskview);    Maddtaskview.setpresenter (this);        } @Override public void Start () {if (mtaskid! = null) {Populatetask (); }} ... @Override public void Populatetask () {if (Mtaskid = = null) {throw new Runtimeex        Ception ("Populatetask () was called and task is new.");    } mtasksrepository.gettask (Mtaskid, this);        } @Override public void ontaskloaded (Task Task) {//The view is able to handle UI updates anymore if (maddtaskview.isactive ()) {Maddtaskview.settitle (Task.gettItle ());        Maddtaskview.setdescription (Task.getdescription ()); }    }    ......}

        

      Here you can see that in addedittaskpresenter it not only implements its own presenter interface, but also implements the Gettaskcallback callback interface. And in the presenter contains the model layer Tasksdatasource object Mtasksrepository and the view Layer Addedittaskcontract.view object Maddtaskview. The entire business logic is then handled in presenter.
      As can be seen from the business process of presenter, first call the model layer interface Gettask method, through TaskID to query task. After querying to a task, the callback interface gettaskcallback of the model layer is implemented in the presenter layer. At this time in the presenter layer through the Ontaskloaded method to get to the task object, and finally by invoking the view layer interface to achieve the data display.

      implementation of the view layer

      The implementation of the view is in fragment, while in activity it completes the addition of the fragment, presenter creation operation. Let's look at the Addedittaskactivity class first.

    • public class Addedittaskactivity extends Appcompatactivity {@Override prot        ected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (r.layout.addtask_act);            ... if (addedittaskfragment = = null) {addedittaskfragment = Addedittaskfragment.newinstance ();            ...... Activityutils.addfragmenttoactivity (Getsupportfragmentmanager (), Addedittaskfragment, R.id.contentFrame        ); }//Create the presenter New Addedittaskpresenter (TaskId, Injection.providet    Asksrepository (Getapplicationcontext ()), addedittaskfragment); }    ......}
      The

      Provides a very simple function for activity, first creating a fragment object and adding it to the activity. The presenter object is then created and fragment, which is the view, is passed to presenter.  
      Look at the implementation of the view below, that is, fragment.

    •  public  class   Addedittaskfragment extends Fragment implements Addedittaskcontract.view {... @Ove Rride  public  void   Onresume () {super.onresume ();    Mpresenter.start (); @Override  public  void   Setpresenter (@NonNull addedittaskcontract.presenter Presenter) {mpresenter  = Checknotnull (presenter); } ... @Override  public  void  
            
              Settitle (String title) {Mtitle.settext (title); }    ......}
            

      In this for the source code is not too much posted. In fragment, the presenter object is obtained through Setpresenter. The processing of the business is accomplished by invoking the method in presenter. In fragment, however, there are just a few things to do with the UI. This reduces the amount of code for the fragment type and makes the logic clearer.
      We note that the implementation of the view layer is done through fragment. Why do you use fragment instead of activity for the view implementation? Take a look at how the official explanation is.

    • The separation between activity and Fragment fits nicely with this implementation of mvp:the activity are the overall cont Roller that creates and connects views and presenters. Tablet layout or screens with multiple views take advantage of the fragments framework.

        

      Here there are two explanations for the reasons for using fragment.

      • The separation of activity and fragment is ideal for the implementation of the MVP architecture. In this case, the activity as a global controller will be associated with the presenter view.
      • Using fragment is more advantageous for tablet layouts or multi-view screens.
      Summarize

      With the use of the MVP architecture, it can be seen that the responsibilities between the levels are more single and clear, and the coupling of the code is reduced to a great extent. For an example of the official MVP architecture, Google also made it clear that the examples of the architectures they gave were only as a reference, not a standard. So there is more room to expand the base MVP architecture. For example, combine the examples given by Google. We can build a clean architecture by using Dagger2,rxjava on the basis of the MVP architecture. is also a good choice.

  • Disclaimer: This article reproduced http://blog.csdn.net/ljd2038/article/details/51477475

The--MVP of Android's common architecture

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.