Android Official Example: Android-architecture study Note (ii) of the TODO-MVP

Source: Internet
Author: User

Project Address: https://github.com/googlesamples/android-architecture/tree/todo-mvp/
In the first article, TODO-MVP is just a branch of the Android-architecture project.

Project structure

TODO-MVP mainly uses the MVP architecture to achieve

The Repository in the graph is the data source, m, including local data and remote data, Fragment is dependent on p,v (Fragment) and P interdependence in v;activity, p relies on M (Repository), i.e. p separates m from V Of course, sometimes we don't need fragment, so we can use activity directly as V

Main package structure and base interface of the project

(Test package not included):

In addition to the Baseview, Basepresenter two interfaces, the other package is divided into business functions:
addedittask--Adding tasks
data--Data source
statistics--Task Statistics
taskdetail--Task Details
tasks--Task List
util--Tool Class

Baseview, basepresenter two interfaces:

publicinterface BaseView<T> {    void setPresenter(T presenter);}publicinterface BasePresenter {    void start();}
Data source Model

First look at the data module, the M

task--It's a Java bean.
Tasksdatasource--task Interface for data manipulation
tasksrepository--realizes the Tasksdatasource, relies on the Taskslocaldatasource, Tasksremotedatasource, realizes the local or the remote related data according to the different situation
tasksremotedatasource--remote data, generally may go network, of course there is no, just analog
taskspersistencecontract--Conventions database table fields
tasksdbhelper--Database Operations
taskslocaldatasource--Local Data source

Note: The local data is only operated by default in the project, and if you want to operate remote, you only need to mcacheisdirty=true the attributes in the tasksrepository.

Tasks Module Analysis

Then pick a business module to analyze (the other modules are similar), such as tasks

scrollchildswiperefreshlayout--This is a custom layout, don't bother
Tasksactivity--activity
taskscontract--contract Interface (each function module has one), agreed to two sub-interfaces view and presenter, and their respective public methods, respectively implement Baseview, basepresenter two interfaces
Tasksfiltertype--enum class, Task filter type
Tasksfragment--fragment to achieve Taskscontract.view
Taskspresenter--presenter to achieve Taskscontract.presenter

Then analyze a specific business function, such as displaying the Tasks list
In Taskscontract#presenter, there is a method:

void loadTasks(boolean forceUpdate);

In the corresponding Taskscontract#view, there is one method:

void showTasks(List<Task> tasks);

Look at some of the code related to Taskspresenter:

 Public  class taskspresenter implements taskscontract. Presenter {    Private FinalTasksrepository mtasksrepository;Private FinalTaskscontract.view Mtasksview;PrivateTasksfiltertype mcurrentfiltering = tasksfiltertype.all_tasks;Private BooleanMfirstload =true; Public Taskspresenter(@NonNull tasksrepository tasksrepository, @NonNull taskscontract.view Tasksview) {mtasksrepository = Checknotnull (Tasksrepository,"Tasksrepository cannot be null"); Mtasksview = Checknotnull (Tasksview,"Tasksview cannot be null!"); Mtasksview.setpresenter ( This); }@Override     Public void Start() {Loadtasks (false); }@Override     Public void Loadtasks(BooleanForceUpdate) {//Simplification for SAMPLE:A network reload would be forced on first load.Loadtasks (forceupdate | | mfirstload,true); Mfirstload =false; }Private void Loadtasks(BooleanForceUpdate,Final BooleanShowloadingui) {if(Showloadingui) {Mtasksview.setloadingindicator (true); }if(forceupdate)        {mtasksrepository.refreshtasks (); }//The network request might is handled in a different thread so make sure Espresso knows        //The app is busy until the response is handled.Espressoidlingresource.increment ();//APP is busy until further noticeMtasksrepository.gettasks (NewTasksdatasource.loadtaskscallback () {@Override             Public void ontasksloaded(list<task> tasks) {List<task> Taskstoshow =NewArraylist<task> ();//This callback is called twice, once for the cache and once for loading                //The data from the server APIs, so we check before decrementing, otherwise                //It throws "Counter has been corrupted!" exception.                if(! Espressoidlingresource.getidlingresource (). Isidlenow ()) {espressoidlingresource.decrement ();//Set app as idle.}//We filter the tasks based on the RequestType                 for(Task task:tasks) {Switch(mcurrentfiltering) { CaseALL_TASKS:tasksToShow.add (Task); Break; CaseActive_tasks:if(Task.isactive ())                            {Taskstoshow.add (Task); } Break; CaseCompleted_tasks:if(Task.iscompleted ())                            {Taskstoshow.add (Task); } Break;default: Taskstoshow.add (Task); Break; }                }//The view May is able to handle UI updates anymore                if(!mtasksview.isactive ()) {return; }if(Showloadingui) {Mtasksview.setloadingindicator (false);            } processtasks (Taskstoshow); }@Override             Public void ondatanotavailable() {//The view May is able to handle UI updates anymore                if(!mtasksview.isactive ()) {return;            } mtasksview.showloadingtaskserror ();    }        }); }Private void Processtasks(list<task> tasks) {if(Tasks.isempty ()) {//Show A message indicating there is no tasks for that filter type.Processemptytasks (); }Else{//Show the list of tasksMtasksview.showtasks (tasks);//Set the filter label ' s text.Showfilterlabel (); }    }}

From the above, it is seen that Taskspresenter relies on tasksrepository, Taskscontract.view, that p relies on M and V; when Loadtasks (Boolean forceupdate, Final Boolean Showloadingui) is called, the data is fetched from M, and the Processtasks (List tasks) is called, and its internal call mtasksview.showtasks (tasks) displays the data on V The last thing to say is that in the Taskspresenter construction method, Mtasksview.setpresenter (this) passes p to V

And then see how v passes p to get the data and show
Tasksfragment, which is the main code for V:

 Public  class tasksfragment extends Fragment implements Taskscontract . View {    PrivateTaskscontract.presenter Mpresenter; Public tasksfragment() {//Requires empty public constructor} Public StaticTasksfragmentnewinstance() {return NewTasksfragment (); }@Override     Public void onCreate(@Nullable Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate); Mlistadapter =NewTasksadapter (NewArraylist<task> (0), Mitemlistener); }@Override     Public void Onresume() {Super. Onresume ();    Mpresenter.start (); }@Override     Public void Setpresenter(@NonNull taskscontract.presenter Presenter)    {Mpresenter = Checknotnull (presenter); }@Nullable    @Override     PublicViewOncreateview(Layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) {Swiperefreshlayout.setonrefreshlistener (NewSwiperefreshlayout.onrefreshlistener () {@Override             Public void Onrefresh() {Mpresenter.loadtasks (false); }        });returnRoot }@Override     Public void Showtasks(list<task> tasks)        {Mlistadapter.replacedata (tasks);        Mtasksview.setvisibility (view.visible);    Mnotasksview.setvisibility (View.gone); }}

Look at Tasksfragment's Onresume (), call Mpresenter.start (), and Mpresenter.start (), call Taskspresenter#loadtasks (FALSE) The Tasksfragment Oncreateview () also registers a listener callback, which is called Taskspresenter#loadtasks (false) when the drop-down is refreshed;

The initialization of P and V is done in the activity
Tasksactivity's main code:

 Public  class tasksactivity extends appcompatactivity {    PrivateTaskspresenter Mtaskspresenter;@Override    protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);        Setcontentview (r.layout.tasks_act); Tasksfragment tasksfragment = (tasksfragment) Getsupportfragmentmanager (). Findfragmentbyid (R.id.contentFram e);if(Tasksfragment = =NULL) {//Create the fragmentTasksfragment = Tasksfragment.newinstance ();        Activityutils.addfragmenttoactivity (Getsupportfragmentmanager (), tasksfragment, r.id.contentframe); }//Create the presenterMtaskspresenter =NewTaskspresenter (Injection.providetasksrepository (Getapplicationcontext ()), tasksfragment);//Load previously saved state, if available.        if(Savedinstancestate! =NULL) {Tasksfiltertype currentfiltering = (tasksfiltertype) savedinstancestate.getserializable (            Current_filtering_key);        Mtaskspresenter.setfiltering (currentfiltering); }    }}

At this point, a complete MVP architecture implementation of the business chain is completed

Android Official Example: Android-architecture study Note (ii) of the TODO-MVP

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.