MVP框架示例讲解

一.代码位置

  • MVP
    此文是在此基础上做的讲解,用于加深印象

二.主要代码介绍

  • MActivity.class
    抽象MActivity代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public abstract class MActivity<P extends BasePresenter> extends Activity {

public P mPresenter;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
initView();
}

@Override
protected void onStart(){
super.onStart();
}

protected void initView(){
if (mPresenter == null) {
mPresenter = getPresenter();//获取 mPresenter
if (this instanceof BaseView){
mPresenter.add((BaseView) this);//将 view 传递到 mPresenter 中
}
}
}

/**
* 获取 Presenter,P 为泛型,返回相对应的Presenter,(RadioPresenter/BTPresenter/MusicPresenter/VideoPresenter/)
* @return
*/
public abstract P getPresenter();

@Override
protected void onResume() {
super.onResume();
}

@Override
protected void onDestroy() {
super.onDestroy();
if(mPresenter != null){
mPresenter.delete();//将 mPresenter 中的 view 删除,防止内存泄漏
mPresenter=null;
}
}
  • BaseActivity.class
    BaseActivity继承MActivity
1
2
3
public abstract class BaseActivity extends MActivity<Presenter> implements View {
...
}
  • MainActivity.class
    应用的MainActivity继承BaseActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MainActivity extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
XService.startService(TestService.class);
XService.bindService(TestService.class,mConnection, Service.BIND_AUTO_CREATE);
XLog.i("Acticity持有的P: "+mPresenter);
mPresenter.onCreate();
}


@Override
public Presenter getPresenter() {
return new Presenter(this);
}
...
}
  • MService.class
    抽象MService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public abstract class MService< P extends BasePresenter> extends Service {

private static final String TAG = "XService";
public P mPresenter;

protected void initView(){
if (mPresenter == null) {
mPresenter = getPresenter();//获取 mPresenter
if (this instanceof BaseView){
mPresenter.add((BaseView) this);//将 view 传递到 mPresenter 中
}
}
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
initView();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}

/**
* 获取 Presenter,P 为泛型,返回相对应的Presenter,(RadioPresenter/BTPresenter/MusicPresenter/VideoPresenter/)
* @return
*/
public abstract P getPresenter();

@Override
public void onDestroy() {
super.onDestroy();
mPresenter.delete();//将 mPresenter 中的 view 删除,防止内存泄漏
mPresenter=null;
}
}
  • BaseService.class

BaseService继承自MService

1
2
3
public abstract class BaseService extends MService<Presenter> implements View {
...
}
  • TestService.class
    应用的TestService继承BaseService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class TestService extends BaseService {

@Override
public void onCreate() {
super.onCreate();
mPresenter.onCreate();
XLog.i("Service持有的P: "+mPresenter);
XLog.i(mPresenter);
}

@Override
public Presenter getPresenter() {
return new Presenter(this);
}
...
}
  • BasePresenter.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public abstract class BasePresenter<V extends BaseView, M extends BaseModel> {

public Context mContext;
private WeakReference<V> mWeakReference;
public M mModel;
public Handler mHandler = new Handler();
public BasePresenter(Context context) {
this.mContext=context;
mModel = getModel();
}

/**
* 获取 model,实现该抽象类的子类必须实现此方法,之后就可以使用 mModel操作Model层业务逻辑
* @return
*/
public abstract M getModel();

/**
* 将 view 添加到弱引用中
* @param view
*/
public void add(V view) {
mWeakReference = new WeakReference<V>(view);
}

/**
* 获取弱引用中的 view
* @return
*/
public V get() {
return mWeakReference == null ? null : mWeakReference.get();
}

/**
* 删除弱引用中的 view
*/
public void delete() {
if (mWeakReference != null) {
mWeakReference.clear();
mWeakReference = null;
}
}
public void onDestroy(){

}
}
  • Presenter.class
    Presenter则继承BasePresenter
1
2
3
public class Presenter extends BasePresenter<View, Model> implements View{
...
}

三.启动流程:

  • MainActivity启动
    创建时会创建并持有一个Presenter
    Presenter.class
1
2
3
4
5
6
7
8
9
10
...   
protected void initView(){
if (mPresenter == null) {
mPresenter = getPresenter();//获取 mPresenter
if (this instanceof BaseView){
mPresenter.add((BaseView) this);//将 view 传递到 mPresenter 中
}
}
}
...

Presenter构建方法中会持有单例model
Presenter.class

1
2
3
4
5
6
...
@Override
public Model getModel() {
return Model.getInstant();
}
...

紧接着调用Presenter的onCreate会将View传入Model
Presenter.class

1
2
3
4
5
6
7
8
9
10
...
public void onCreate(){
mModel.onCreate();
addView();
}

public void addView(){
mModel.setViews(this);
}
...

添加到Model的Views集合
Model.class

1
2
3
4
5
6
7
private static ArrayList<View> mViews=new ArrayList<View>();
...
public void setViews(View mPV){
XLog.i("Model中增加P"+mPV);
mViews.add(mPV);
}
...

打印如下

1
2
3
4
45.831  I/MainActivity.java: [ (MainActivity.java:23)#onCreate ] Acticity持有的P_id: @26f08e
45.832 I/Model.java: [ (Model.java:27)#onCreate ] execute
45.847 I/Model.java: [ (Model.java:36)#onResume ] execute
45.849 I/Model.java: [ (Model.java:15)#setViews ] Model中增加P@26f08e

此时单例Model和Activity的Presenter就创建起来,Model中的生产出的值就会通过接口传出到Activity中
紧接着Activity启动并绑定Service

  • Service启动
    同理过程中也会创建一个Service的Presenter,紧接着Presenter也会把View添加到单例model的Views中
1
2
3
45.900  I/TestService.java: [ (TestService.java:21)#onCreate ] Service持有的P_id: @1a5879a
45.901 I/TestService.java: [ (TestService.java:22)#onCreate ] @1a5879a
45.903 I/Model.java: [ (Model.java:15)#setViews ] Model中增加P@1a5879a

此时MVP框架的应用就创建完成,此时存活着一个Activity和对应的Presenter,一个Service和对应的Presenter,一个Model

四.运行

Model中生产的值通过遍历View分别传出
Model.class
我简单创建了一个Handler,每秒+1,并值传出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
private mHandler handler;
private int i = 0;
private class mHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
handler.removeMessages(0x01);
handler.sendEmptyMessageDelayed(0x01,1000);
++i;
for (View mView : mViews) {
XLog.i(mView+" 发送传出处理的值:"+i);
mView.onTime(i);
}
}
}
...

该值首先会通过View传到对应的Presenter,紧接着传出到实现了View方法的Activity和Service

1
2
3
4
@Override
public void onTime(int position) {
get().onTime(position);
}

收到来着Model的数据
MVP的特性才展现出来
打印如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
45.915  I/Model.java: [ (Model.java:68)#handleMessage ] @26f08e 发值:1
45.918 I/MainActivity.java: [ (MainActivity.java:81)#onTime ] @26f08e收值:1
45.920 I/Model.java: [ (Model.java:68)#handleMessage ] @1a5879a 发值:1
45.924 I/TestService.java: [ (TestService.java:47)#onTime ] @1a5879a收值:1

46.918 I/Model.java: [ (Model.java:68)#handleMessage ] @26f08e 发值:2
46.920 I/MainActivity.java: [ (MainActivity.java:81)#onTime ] @26f08e收值:2
46.925 I/Model.java: [ (Model.java:68)#handleMessage ] @1a5879a 发值:2
46.926 I/TestService.java: [ (TestService.java:47)#onTime ] @1a5879a收值:2

47.922 I/Model.java: [ (Model.java:68)#handleMessage ] @26f08e 发值:3
47.923 I/MainActivity.java: [ (MainActivity.java:81)#onTime ] @26f08e收值:3
47.927 I/Model.java: [ (Model.java:68)#handleMessage ] @1a5879a 发值:3
47.928 I/TestService.java: [ (TestService.java:47)#onTime ] @1a5879a收值:3

五.灵活添加和移除view

  • 移除
    当Activity销毁时,通过onDestroy的方法除Model中对应Presenter的View,防止泄漏
    Model.class
1
2
3
4
5
6
7
...
public void onDestroy(View mPV) {
XLog.i("Model中去除P"+mPV);
mViews.remove(mPV);
...
}
...

打印如下:

1
52:03.088  I/Model.java: [ (Model.java:49)#onDestroy ] Model中去除P_id: @170acea
  • 添加
    当Activity再次创建时,model中会再增加其新的对应Presenter的View
1
2
52:07.186  I/MainActivity.java: [ (MainActivity.java:23)#onCreate ] Acticity持有的P_id: @b79a950
52:07.207 I/Model.java: [ (Model.java:15)#setViews ] Model中增加P_id: @b79a950

当不再有Presenter持有Model时,Model会被释放
Model.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
public void onDestroy(View mPV) {
XLog.i("Model中去除P"+mPV);
mViews.remove(mPV);
if (mViews.size()==0){
clear();
}
}


public final void clear() {
handler.removeMessages(0x01);
handler = null;
mModel = null;
}
...

六.补充BaseActivity和BaseService

是属于逻辑层的两个方法,用于逻辑与界面分离时,当逻辑层添加了新的接口时,界面并不需要,或者没来得及实现时,在逻辑层的BaseActivity和BaseService中添加了接口,界面层就不需要去实现。