Android MVP
- coding
- android
- designframework
Preface
As we mention in MVC/MVP/MVVM, MVP
has fixed many problems in MVC
.
MVP
decouples theView
andController
.- Logics about UI and business are extracted to the
Presenter
, making it easier to read the code. Presenter
is based on Interface, making it much more flexible and convienient to do unit test.- The resources in
Activity
can be recycled to avoid memory leak and OOM.
Example
Preview
I’ll make an example with a login activity, just like the one below.
Architecture
(This sketch is from segmentfault.com.)
We build up an Interface
named ILoginPresenter
, which stands for the basic Presenter
.
Then we create a class LoginPresenterImpl
to implement the ILoginPresenter
. Its construction method must have an argument ILoginView
, which is a actually an Interface
stands for the basic View
.
And in fact, Activity
is class to implement the ILoginView
, which means the LoginPresenterImpl
keeps a reference to the Activity
.
ILoginPresenter
Here I implement some basic functionalities, like clearing an EditText
, checking the user name and password.
public interface ILoginPresenter {
void clear(View v);
void doLogin(String userName, String pwd);
void setProgressBarVisibility(int visibility);
}
ILoginView
I need to implement some methods that can be called when the corresponding methods in LoginPresenterImpl
are invoked.
public interface ILoginView {
void onClearText(View v);
void onResult(boolean pass);
void onSetProgressBarVisibility(int visibility);
}
LoginPresenterImpl
LoginPresenterImpl
is a class to implement ILoginPresenter
.
public class LoginPresenterImpl implements ILoginPresenter {
private ILoginView mLoginView;
private Handler handler;
public LoginPresenterImpl(ILoginView loginView) {
mLoginView = loginView;
handler = new Handler();
}
@Override
public void clear(View v) {
mLoginView.onClearText(v);
}
@Override
public void doLogin(final String userName, final String pwd) {
mLoginView.onSetProgressBarVisibility(View.VISIBLE);
handler.postDelayed(new Runnable() {
@Override
public void run() {
boolean pass = userName.equals(Constant.USER_NAME) && pwd.equals(Constant.PASSWORD);
mLoginView.onResult(pass);
mLoginView.onSetProgressBarVisibility(View.GONE);
}
}, 2000);
}
@Override
public void setProgressBarVisibility(int visibility) {
mLoginView.onSetProgressBarVisibility(visibility);
}
}
As we can see, inside methods, the methods of ILoginView
are called. Handler
is used here just to make delay on purpose.
Activity
To be exact, the Activity
is a LoginViewImpl
.
public class MVPActivity extends AppCompatActivity implements ILoginView, View.OnClickListener {
private LoginPresenterImpl mPresenter;
private Button mButtonLogin, mButtonClear;
private EditText mEditTextUserName, mEditTextPassword;
private ProgressBar mProgressBar;
mPresenter = new LoginPresenterImpl(this);
@Override
public void onClearText(View v) {
if (v.getId() == R.id.btn_clear) {
mEditTextPassword.setText("");
mEditTextUserName.setText("");
}
}
@Override
public void onResult(boolean pass) {
Toast.makeText(this, pass ? "success" : "fail", Toast.LENGTH_SHORT).show();
}
@Override
public void onSetProgressBarVisibility(int visibility) {
mProgressBar.setVisibility(visibility);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_login:
mPresenter.doLogin(mEditTextUserName.getText().toString(), mEditTextPassword.getText().toString());
break;
case R.id.btn_clear:
mPresenter.clear(v);
break;
}
}
}
Inside the methods implemented by MVPActivity
, we do the work.
Now, the Presenter
is commucating with View(Activity)
and Model
and View
is totally separated. Since we don’t have Model
here, I am not able to show more about it.
Hope you have a better understanding of MVP
in Android development.