简单的MVP, 写于2017年,传上来做个记录。 公司还是用的MVC,有好的MVP框架欢迎留言。
MVP模式
View 负责View的绘制以及与用户交互,是Activity(下图中的activity目录)
Model 是业务逻辑模型和实体模型,实际是一个接口(下图中的view目录)
Presenter 负责完成View于Model间的交互,(下图中的presenter目录)
封装原因:
1、BaseView(modle)
有很多类似方法,如获取数据,显示隐藏对话框,写一个公共的父类接口,这样不用每个model都写相同的接口。
2、BaseActivity(view) 1)实例化Presenter
2)onCreate时model绑定到presenter,onDestoty时解绑。这样不用每个Presenter都绑定和解绑model
3、BasePresenter (presenter) 提供绑定解绑View 的方法 一、Base 1、BaseView 定义所有视图通用的接口
public interface BaseView {
/**显示进度框*/
void showDialogProgress();
/**隐藏进度框*/
void dismissDialogProgress();
/**加载数据*/
void loadData();
/**
*所有请求数据的地方都可以通用。
*/
void loadDataOver(int type, Object object);
/** 显示失败信息 */
void loadDataError(Throwable e, int code);
}
2、BaseParenter 绑定View, Activity,onDestory时解绑
public abstract class BasePresenter<V extends BaseView> {
protected V mView;
private BaseActivity mActivityPresenter;
//获取model实例
public void attach(V mView) {
this.mView = mView;
}
//解绑model,activity onDestroy 时执行
public void detach() {
mView = null;
}
//获取Activity
public void setActivity(BaseActivity mActivity) {
this.mActivityPresenter = mActivity;
}
//解绑Activity,activity onDestroy 时执行
public void deleteActivity() {
mActivityPresenter = null;
}
protected Activity getActivity() {
return mActivityPresenter;
}
}
3、BaseActivity
public abstract class BaseActivity<V extends BaseView, T extends BasePresenter<V>> extends AppCompatActivity implements BaseView,BaseFragment.OnFragmentInteractionListener {
protected String TAG = getClass().getSimpleName();
protected T mPresenter;
protected BaseActivity mActivity;
protected ProgressDialog mDialogProgress;//进度对话框
public static boolean isAlive = false;//是否存活
public static boolean isRunning = false;//页面是否运行显示
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = BaseActivity.this;
isAlive = true;
setContentView(bindLayout());
attachPresenter();
loadData();
}
//将model绑定Presenter
private void attachPresenter() {
mPresenter = initPresenter();
if (mPresenter != null) {
mPresenter.attach((V) this);//presenter绑定view
mPresenter.setActivity(mActivity);
}
}
/**实例化presenter*/
public abstract T initPresenter();
/**[绑定布局] @return 布局id 必须执行 绑定布局*/
@LayoutRes
public abstract int bindLayout();
@Override
protected void onResume() {
super.onResume();
isRunning = true;
}
@Override
protected void onPause() {
super.onPause();
isRunning = false;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
if (mPresenter != null) {
mPresenter.detach();
mPresenter.deleteActivity();
}
super.onDestroy();
isAlive = false;
isRunning = false;
mPresenter = null;
}
@Override
public boolean isRunning() {
return isRunning;
}
@Override
public boolean isAlive() {
return isAlive && mActivity != null;// & ! isFinishing();导致finish,onDestroy内runUiThread不可用
}
@Override
public void showDialogProgress() {
}
@Override
public void dismissDialogProgress() {
}
protected final void runUiThread(Runnable action) {
if (this.isFinishing()) {
Log.w(TAG, "runUiThread isAlive() == false >> return;");
return;
}
runOnUiThread(action);
}
@Override
public void onFragmentInteraction(Bundle bundle) {}
}
}
二、实现 1.MainView(model) 添加MainActivity要实现的方法。
public interface MainView extends BaseView{
void onRequestSuccess();
}
2.MainParenter(parenter)
主要负责Activity的逻辑处理,处理完成后将结果通过接口mView 传递给Activity中, 通知Activity 的视图的改变。
public class MainPresenter extends BasePresenter<MainView> {
int page;
//模拟请求网络
public void request() {
mView.showDialogProgress();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
page++;
mView.dismissDialogProgress();
mView.loadDataOver(1, page);//这个要更新View 必须在UI线程执行。
mView.onRequestSuccess();
}
});
}
}).start();
}
}
3.MainActivity(view)
public class MainActivity extends BaseActivity<MainView, MainPresenter> implements MainView {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
findViewById(R.id.btn_load).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPresenter.request();
}
});
}
@Override
public MainPresenter initPresenter() {
return new MainPresenter();
}
@Override
public int bindLayout() {
return R.layout.activity_main;
}
@Override
public void loadData() {
mPresenter.request();
}
@Override
public void loadDataOver(int type, Object object) {
((TextView) findViewById(R.id.tv_info)).setText("page " + Integer.parseInt(String.valueOf(object)));
}
@Override
public void loadDataError(Throwable e, int code) {
}
@Override
public void onRequestSuccess() {
Toast.makeText(getApplicationContext(),"成功",Toast.LENGTH_SHORT).show();
}
}