Talking about MVP in Android and mvpinandroid
Reprinted please indicate the source:
Http://blog.csdn.net/lmj623565791/article/details/10996133;
This article is from: [Zhang Hongyang's blog]
I. Overview
Most MVPs (Model View Presenter) can say one or two: "Evolution of MVC", "completely decoupling Model and View. This blog post only aims to record the content, give some comments, and help you write MVP-style code for an Activity page.
I have a question in my heart:
Why can this model be accepted by the majority of Android programmers?
Some programmers have been asked about MVP's general understanding: "The Code is clear, but many classes have been added ". When I first saw the MVP, I read a demo and thought it was very nice after reading it. (but when I looked back, I thought of an example to write it, so I couldn't write it out with a headache, of course, this will be said later ). The reason for nice is that this mode does greatly improve the definition of the Code.
The improvements are generally compared. Looking back, there is no MVP code structure applied. Most people say it is MVC:
- View: corresponds to the layout File
- Model: business logic and entity Model
- Controllor: corresponds to Activity
It looks like this, but I think this Model corresponds to the layout file. In fact, there are only a few things that can be done. In fact, the Data Binding operations in this layout file, all the code for event processing is in the Activity, which makes the Activity both like View and Controller (of course, the appearance of Data-Binder may make the Model more like Model ). This may be why, in this article, there is a sentence like this:
Most of the modern Android applications just use View-Model architecture, everything is connected with Activity.
After the architecture is changed to MVP, the appearance of Presenter regards Actvity as the View layer, and the Presenter completes the interaction between the View layer and the Model layer. Now it is like this:
- View corresponds to Activity and is responsible for drawing and interacting with users.
- Model is still the business logic and entity Model
- Presenter is responsible for completing the interaction between views and models.
OK. First, let's take a look at some examples in this article.
In summary, that is to say, the reason why this jump is refreshing is fromNon-standard MVC
ToMVP
It reduces the Activity's responsibilities, simplifies the code in the Activity, and extracts complicated logic code into the Presenter for processing. The corresponding advantage is that the coupling degree is lower and testing is more convenient. Borrow two graphs (from: This article) to represent the above transformation:
To:
Ii. Differences between MVP and MVC
Okay, I have mentioned a bunch of theories above. Next we still need to take a look at the difference between MVC and MVP. Please refer to (from: This article ):
In fact, the most obvious difference is that in MVC, Model and View are allowed to interact, while in MVP, it is obvious that the interaction between Model and View is completed by the Presenter. Another point is that the interaction between the Presenter and the View is through the interface (which will be reflected in the Code ).
There is also a bunch of conceptual things, and the advantages are omitted, interested in Baidu. Below are some simple requirements to show how to compile the MVP demo.
Iii. Simple Login Demo
:
To see this effect, first look at the project structure after completion:
OK. Let's start writing ideas step by step.
(1) Model
First, the entity class User does not need to consider this. Second, we can see at least one business method login (). These two methods are not difficult. We should first complete:
package com.zhy.blogcodes.mvp.bean;/** * Created by zhy on 15/6/18. */public class User{ private String username ; private String password ; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
package com.zhy.blogcodes.mvp.biz;/** * Created by zhy on 15/6/19. */public interface IUserBiz{ public void login(String username, String password, OnLoginListener loginListener);}
Package com. zhy. blogcodes. mvp. biz; import com. zhy. blogcodes. mvp. bean. user;/*** Created by zhy on 15/6/19. */public class UserBiz implements IUserBiz {@ Override public void login (final String username, final String password, final OnLoginListener loginListener) {// simulate time-consuming operations of sub-threads new Thread () {@ Override public void run () {try {Thread. sleep (2000);} catch (InterruptedException e) {e. printStackTrace ();} // simulate Successful Logon if ("zhy ". equals (username) & "123 ". equals (password) {User user = new User (); user. setUsername (username); user. setPassword (password); loginListener. loginSuccess (user);} else {loginListener. loginFailed ();}}}. start ();}}
package com.zhy.blogcodes.mvp.biz;import com.zhy.blogcodes.mvp.bean.User;/** * Created by zhy on 15/6/19. */public interface OnLoginListener{ void loginSuccess(User user); void loginFailed();}
Needless to say, as for the business class, we have extracted an interface, and an implementation class is also very common ~~ The login method is usually used to connect to the server. It is a time-consuming operation, so we opened up the Sub-Thread, Thread. sleep (2000) simulates the time consumption. Because it is a time-consuming operation, we use a callback interface to notify the logon status.
In fact, it is quite easy to write here, because it is no different from traditional writing.
(2) View
As mentioned above, Presenter interacts with View through interfaces. Therefore, we need to defineILoginView
The difficulty lies in the methods. Let's take a look:
We can see two buttons: login and clear;
Login indicates that a user name and password are required. The two methods are as follows:
String getUserName(); String getPassword();
Furthermore, login is a time-consuming operation. We need to give the user a friendly prompt, which is generally the ProgressBar operation, so there are two more:
void showLoading(); void hideLoading();
Of course, login can handle login success and failure. We mainly consider that success is a jump to Activity, and failure may be a reminder:
void toMainActivity(User user); void showFailedError();
OK. We have analyzed the login method ~~ The remaining clear is simple:
void clearUserName(); void clearPassword();
In summary, the interface is complete:
package com.zhy.blogcodes.mvp.view;import com.zhy.blogcodes.mvp.bean.User;/** * Created by zhy on 15/6/19. */public interface IUserLoginView{ String getUserName(); String getPassword(); void clearUserName(); void clearPassword(); void showLoading(); void hideLoading(); void toMainActivity(User user); void showFailedError();}
With the interface, the implementation is too good to write ~~~
In summary, for the View Interface, observe the functional operations, and then consider:
- What does this operation require? (GetUserName, getPassword)
- What is the corresponding feedback for the result of this operation? (ToMainActivity, showFailedError)
- What is the friendly interaction during this operation? (ShowLoading, hideLoading)
Next I will post the implementation class of our View. HA is actually Activity. At the beginning of the article, I said that the View in MVP is actually Activity.
package com.zhy.blogcodes.mvp;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ProgressBar;import android.widget.Toast;import com.zhy.blogcodes.R;import com.zhy.blogcodes.mvp.bean.User;import com.zhy.blogcodes.mvp.presenter.UserLoginPresenter;import com.zhy.blogcodes.mvp.view.IUserLoginView;public class UserLoginActivity extends ActionBarActivity implements IUserLoginView{ private EditText mEtUsername, mEtPassword; private Button mBtnLogin, mBtnClear; private ProgressBar mPbLoading; private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_login); initViews(); } private void initViews() { mEtUsername = (EditText) findViewById(R.id.id_et_username); mEtPassword = (EditText) findViewById(R.id.id_et_password); mBtnClear = (Button) findViewById(R.id.id_btn_clear); mBtnLogin = (Button) findViewById(R.id.id_btn_login); mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading); mBtnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.login(); } }); mBtnClear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.clear(); } }); } @Override public String getUserName() { return mEtUsername.getText().toString(); } @Override public String getPassword() { return mEtPassword.getText().toString(); } @Override public void clearUserName() { mEtUsername.setText(""); } @Override public void clearPassword() { mEtPassword.setText(""); } @Override public void showLoading() { mPbLoading.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mPbLoading.setVisibility(View.GONE); } @Override public void toMainActivity(User user) { Toast.makeText(this, user.getUsername() + " login success , to MainActivity", Toast.LENGTH_SHORT).show(); } @Override public void showFailedError() { Toast.makeText(this, "login failed", Toast.LENGTH_SHORT).show(); }}
It is easy to implement the interface defined above in the Activity. After all, the interface guides us to complete.
Finally, let's look at our Presenter.
(3) Presenter
Presenter is used as a bridge between Model and View. How can this problem be solved?
In fact, it mainly depends on the operation of this function, such as this example, two operations: login and clear.
Package com. zhy. blogcodes. mvp. presenter; import android. OS. handler; import com. zhy. blogcodes. mvp. bean. user; import com. zhy. blogcodes. mvp. biz. IUserBiz; import com. zhy. blogcodes. mvp. biz. onLoginListener; import com. zhy. blogcodes. mvp. biz. userBiz; import com. zhy. blogcodes. mvp. view. IUserLoginView;/*** Created by zhy on 15/6/19. */public class UserLoginPresenter {private IUserBiz userBiz; private IUserLoginView userLoginView; private Handler mHandler = new Handler (); public UserLoginPresenter (IUserLoginView userLoginView) {this. userLoginView = userLoginView; this. userBiz = new UserBiz ();} public void login () {userLoginView. showLoading (); userBiz. login (userLoginView. getUserName (), userLoginView. getPassword (), new OnLoginListener () {@ Override public void loginSuccess (final User user) {// mHandler needs to be executed in the UI thread. post (new Runnable () {@ Override public void run () {userLoginView. toMainActivity (user); userLoginView. hideLoading () ;}}) ;}@ Override public void loginFailed () {// mHandler needs to be executed in the UI thread. post (new Runnable () {@ Override public void run () {userLoginView. showFailedError (); userLoginView. hideLoading () ;}}) ;}} public void clear () {userLoginView. clearUserName (); userLoginView. clearPassword ();}}
Pay attention to the above Code. If our presenter completes the interaction between the two, the implementation class of the two is required. It is generally to obtain the required parameters from the View, hand them to the Model to execute the business method, the feedback and results required during the execution, and then display the View accordingly.
OK. After getting an example, the above decomposition is basically complete. The above are purely personal opinions. Welcome to discuss and speak out ~ Have a nice day ~.
Download source code
Public Account: hongyangAndroid
(Please pay attention to it and push blog information as soon as possible)
References
- Https://github.com/zhengxiaopeng/Rocko-Android-Demos/tree/master/android-mvp
- Https://github.com/antoniolg/androidmvp
- Https://github.com/pedrovgs/EffectiveAndroidUI
- Http://zhengxiaopeng.com/2015/02/06/Android%E4%B8%AD%E7%9A%84MVP/
- Http://magenic.com/Blog/Post/6/An-MVP-Pattern-for-Android
- Http://antonioleiva.com/mvp-android/
- Http://konmik.github.io/introduction-to-model-view-presenter-on-android.html