前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XYLibrary笔记六:再理MVP框架

XYLibrary笔记六:再理MVP框架

作者头像
项勇
发布2023-03-24 13:22:48
2500
发布2023-03-24 13:22:48
举报
文章被收录于专栏:项勇项勇

此文是借鉴于XTLib中的mvp模式上做的讲解,以加强对框架的理解

1.主要代码介绍

抽象MActivity代码

MActivity.class

代码语言:javascript
复制
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继承MActivity

BaseActivity.class

代码语言:javascript
复制
public abstract class BaseActivity extends MActivity<Presenter> implements View {
    ...
}

应用的MainActivity继承BaseActivity

MainActivity.class

代码语言:javascript
复制
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

代码语言:javascript
复制
MService.class
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继承自MService

BaseService.class

代码语言:javascript
复制
public abstract class BaseService extends MService<Presenter> implements View {
    ...
}

应用的TestService继承BaseService

TestService.class

代码语言:javascript
复制
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

代码语言:javascript
复制
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则继承BasePresenter

Presenter.class

代码语言:javascript
复制
public class Presenter extends BasePresenter<View, Model> implements View{
    ...
}

2.启动流程:

2.1MainActivity启动

初始化时会创建并持有一个Presenter

Presenter.class

代码语言:javascript
复制
...   
 protected void initView(){
        if (mPresenter == null) {
            mPresenter = getPresenter();//获取 mPresenter
            if (this instanceof BaseView){
                mPresenter.add((BaseView) this);//将 view 传递到 mPresenter 中
            }
        }
    }
...

resenter构建方法中持有单例model

Presenter.class

代码语言:javascript
复制
...
@Override
public Model getModel() {
    return Model.getInstant();
}
...

着调用Presenter的onCreate会将View传入Model

Presenter.class

代码语言:javascript
复制
...
public void onCreate(){
    mModel.onCreate();
    addView();
}
public void addView(){
    mModel.setViews(this);
}
...

添加到Model的Views集合

Model.class

代码语言:javascript
复制
private static ArrayList<View> mViews=new ArrayList<View>();
...
public void setViews(View mPV){
    XLog.i("Model中增加P"+mPV);
    mViews.add(mPV);
}
...

打印如下

代码语言:javascript
复制
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

2.2 Service启动

同理过程中也会创建一个Service的Presenter,接着Presenter也会把View添加到单例model的Views中

代码语言:javascript
复制
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

3.运行

Model中生产的值通过遍历View分别传出

我简单创建了一个Handler,每秒+1,并值传出来

Model.class

代码语言:javascript
复制
...
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

代码语言:javascript
复制
@Override
public void onTime(int position) {
    get().onTime(position);
}

Activity和Service都会收到来自单例Model传过来的数据

MVP的特性才展现出来

打印如下

代码语言:javascript
复制
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

4.灵活添加和移除View

4.1 移除

当Activity销毁时,通过onDestroy的方法除Model中对应Presenter的View,防止泄漏

Model.class

代码语言:javascript
复制
...
public void onDestroy(View mPV) {
    XLog.i("Model中去除P"+mPV);
    mViews.remove(mPV);
    ...
}
...

打印如下:

代码语言:javascript
复制
52:03.088  I/Model.java: [ (Model.java:49)#onDestroy ] Model中去除P_id: @170acea

4.2 添加

当Activity再次创建时,model中会再增加其新的对应Presenter的View

代码语言:javascript
复制
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

代码语言:javascript
复制
...
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;
}
...

5.补充BaseActivity和BaseService

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 项勇 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档