由于前段时间面试,发现大多数公司开始问MVP模式,你会不会这种框架牧师,那时候表示不会,所以现在来恶补一下。
首先:什么是MVP模式?说一下我的理解。
M(Model层):在android中主要是处理数据的存在。比如你界面有一个按钮需要请求网络校验数据,那么校验数据的这步就应该放在Model层。
V(View层):这个就很好理解了,界面相关的东西都在View层,比如Activity,Fragment,adapter。界面层主要提供与人的交互,比如我该怎么显示,失败与成功各要显示什么,与用户提供什么样的交互。
P(Presenter层):这个相当于逻辑处理层。处理View想干的事情。比如说点击这个按钮你想去登录,那么就调用doLogin方法。想去下载图片就去调用doDownLoad方法。这一层主要是要去干什么,而不是怎么干。
然后:我们为什么要使用这种模式。
使用这种模式之前我们的开发模式都是MV模式的。把View 和 Presenter放在一起。比如我们有一个activity用于登录:LoginActivity,它的作用是收集用户输入的用户名和密码然后去Net校验。
以前我们写这种功能也很好实现。2个EditText分别输入用户名和密码,1个Button处理数据提交,写一个login方法传入edittext获取的用户名密码访问网络。一切的一切全写在Activity中了。这样写的好处是什么,简单的项目我们很快就能完成。此时如果我们有一个activity,它上面布满了各种控件,各种需要处理的事件。我们想象一下这个activity中要有多少个方法,有多少行代码,这样会造成可读性很差。这时候MVP就出现了。。。它相当于把一个activity处理数据界面展示等分成了3个部分。提高了代码的可读性。现如今大型项目几乎都已经开始使用这种模式了。
最后:我们来看一个简单的例子。
先来看一下这个目录结构model主要用于存储数据相关,View主要用于存储UI相关 ,presenter主要用于储存行为相关。
View层代码:
ILoginView接口
MAinActivity.javapackage com.example.myapplication.login.view; public interface ILoginView { public String getUserName(); public String getPassWord(); public void showProgressBar(); public void hideProgressBar(); public void showSuccMsg(); public void showErrorMsg(); }
package com.example.myapplication.login.view; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.Toast; import com.example.myapplication.R; import com.example.myapplication.login.presenter.IPresenter; import com.example.myapplication.login.presenter.LoginPresents; import butterknife.BindView; import butterknife.ButterKnife; public class MainActivity extends AppCompatActivity implements ILoginView{ @BindView(R.id.editUser) public EditText userName; @BindView(R.id.editPass) public EditText userPass; @BindView(R.id.login) public Button login; @BindView(R.id.progressbar) public ProgressBar mProgressBar; private LoginPresents loginPresents; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); ButterKnife.bind(this); loginPresents=new LoginPresents(this); login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { loginPresents.doLogin(); } }); } @Override public String getUserName() { return userName.getText().toString(); } @Override public String getPassWord() { return userPass.getText().toString(); } @Override public void showProgressBar() { mProgressBar.setVisibility(View.VISIBLE); } @Override public void hideProgressBar() { mProgressBar.setVisibility(View.GONE); } @Override public void showSuccMsg() { Toast.makeText(MainActivity.this,"login succ",Toast.LENGTH_LONG).show(); } @Override public void showErrorMsg() { Toast.makeText(MainActivity.this,"login fail",Toast.LENGTH_SHORT).show(); } }
Model层代码:
Userbean.java
package com.example.myapplication.login.model; public class UserBean { public String userName; public String userPassWord; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassWord() { return userPassWord; } public void setUserPassWord(String userPassWord) { this.userPassWord = userPassWord; } }ILoginModel接口
package com.example.myapplication.login.model; public interface ILoginModel { public void checkUser(String user ,String pass,CallBack callBack); interface CallBack{ void Success(); void Fail(); } }LgoinModel.java
package com.example.myapplication.login.model; import java.util.logging.Handler; public class LoginModel implements ILoginModel { //模拟网络请求 @Override public void checkUser(String user, String pass, final CallBack callBack) { new android.os.Handler().postDelayed(new Runnable() { @Override public void run() { callBack.Success(); } }, 3000); } }Presenter层代码:
Ipresenter接口
package com.example.myapplication.login.presenter; import com.example.myapplication.login.view.ILoginView; public interface IPresenter { public void doLogin(); }LoginPresenter.java
package com.example.myapplication.login.presenter; import com.example.myapplication.login.model.ILoginModel; import com.example.myapplication.login.model.LoginModel; import com.example.myapplication.login.view.ILoginView; public class LoginPresents implements IPresenter { private ILoginView loginView; private LoginModel loginModel; public LoginPresents(ILoginView view){ loginView=view; loginModel=new LoginModel(); } @Override public void doLogin() { loginView.showProgressBar(); loginModel.checkUser(loginView.getUserName(), loginView.getPassWord(), new ILoginModel.CallBack() { @Override public void Success() { loginView.hideProgressBar(); loginView.showSuccMsg(); } @Override public void Fail() { loginView.hideProgressBar(); loginView.showErrorMsg(); } }); } }
所有代码就是这些。MVP层一定会有3个接口,ILoginModel,ILoginView,IPresenter。
它们之间的逻辑是MainActivty中的按钮点击调用了行为层(presenter)的LoginPresenter去实现登录功能,LoginPresenter去调用数据层(Model)的LoginModel执行网络处理操作得到返回数据,然后再传递给View层(MainActivity.java)。
对于MVP我想说的是越难的项目感觉代码看起来越清晰,但是简单的项目还是不要用了。会多写很多代码。。。。。