Introduction to MVP
I believe that everyone is familiar with MVC: M-Model-model, V-View-view, C-Controller-controller, MVP as an evolved version of MVC, is also an implementation mode of user interface (user layer), so similar The corresponding meaning of MVP: M-Model-model, V-View-view, P-Presenter-presenter.
For details on MVC, see the blog: The use of Android's MVC pattern
Model
Model is the abstraction of the data that the user interface needs to display, and it can also be understood as the abstraction from business data (results) to the user interface.
View
The view layer is very thin and light, and is responsible for displaying data and providing a friendly interface to interact with users. Activity and Fragment under MVP are reflected in this layer. Activity generally does some work of loading UI views, setting monitoring, and then handing it over to the Presenter, so it needs to hold a reference to the corresponding Presenter.
Presenter
The Presenter layer handles the distribution of various logics of the program. After receiving the feedback commands, timing commands, system commands and other instructions on the UI of the View layer, the distribution processing logic is handed over to the business layer for specific business operations, and then the obtained Model is sent to the View display.
The difference between MVC and MVP
In MVC :
- View can interact directly with Model ;
- Controller can be shared by multiple Views ;
- The Controller can decide which View to display .
In MVP :
- View does not directly interact with Model ;
- Presenter interacts with View through interfaces, which is more conducive to adding unit tests;
- Usually View and Presenter are one-to-one, but complex View may be bound to multiple Presenters for processing;
- Presenter can also directly render on View .
Imitate the login case: ( The demo contains login and network data requests)
model
public class ModelSignIn implements ILoginSignIn { @Override public void onSignIn(String name, String pwd, IOnSetListenter listenter) { if (name.isEmpty()) { if (listenter!=null) { listenter.onError("The input username is empty"); return; } } if (pwd.isEmpty()) { if (listenter!=null) { listenter.onError("The input password is empty"); return; } } if(name.equals("dickyqie") && pwd.equals("123456")) { if (listenter!=null) { listenter.onError("Login successful"); return; } }else{ if (listenter!=null) { listenter.onError("Login failed"); return; } } } }
presenter
public class Presenter extends BasePresenter<IView> { ILoginSignIn iLoginSignIn=new ModelSignIn(); public void setSignIn(String name,String pwd) { iLoginSignIn.onSignIn(name, pwd, new ILoginSignIn.IOnSetListenter() { IView view=getView(); @Override public void onError(String error) { if(view!=null){ view.showToast(error); } } @Override public void onSccess(String repsonce) { if(view!=null){ view.showToast(repsonce); } } }); } }
activity
public class MainActivity extends BaseActivity<IView,Presenter> implements IView,View.OnClickListener{ EditText username; EditText password; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { username=(EditText)findViewById(R.id.username); password=(EditText)findViewById(R.id.password); findViewById(R.id.login).setOnClickListener(this); } @Override public Presenter createPersenter() { return new Presenter(); } @Override public void onClick(View v) { String name=username.getText().toString(); String pwd=password.getText().toString(); p.setSignIn(name,pwd); } @Override public void showToast(String msg) { Toast.makeText(getApplicationContext(),msg,Toast.LENGTH_LONG).show(); } }
network request
public class MainActivity extends BaseActivity<IView,Presenter> implements IView,View.OnClickListener { private TextView textView; private ProgessDialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView(){ textView=(TextView) findViewById(R.id.text); findViewById(R.id.btn).setOnClickListener(this); } @Override public void onLoadContributorStart() { showProgress(); } @Override public void onLoadContribtorComplete(String topContributor) { // get the data of the main thread Message msg=new Message(); msg.what=1; msg.obj=topContributor; handler.sendMessage(msg); } Handler handler = new Handler () { @Override public void handleMessage(Message msg) { super.handleMessage(msg); dismissProgress(); textView.setText(msg.obj.toString()); } }; @Override public void onClick(View v) { p.setGet(); } @Override public Presenter createPresenter() { return new Presenter(); } @Override public void onNetWork() { Toast.makeText(getApplicationContext(),"Network not connected",Toast.LENGTH_LONG).show(); } @Override public void onError() { Toast.makeText(getApplicationContext(),"Data load failed",Toast.LENGTH_LONG).show(); textView.setText(""); } /*** * start up */ public void showProgress() { if(dialog==null) { dialog=new ProgessDialog(MainActivity.this); } dialog.showMessage("Loading"); } /*** * closure */ public void dismissProgress() { if(dialog==null) { dialog=new ProgessDialog(this); } dialog.dismiss(); } }
Don't forget to add permissions in AndroidManifest.xml!
<uses-permission android:name="android.permission.INTERNET"/>
Due to too much code, the complete code is not given, the source code can be downloaded directly