Android MVP实践

在上篇博文 一款安卓TV上使用的蓝牙和WiFi测试工具 的基础上再记录一下学校MVP架构的心得,方便理解和后续追溯。

如有不对的地方,请指正交流

在18年年初和别人配合协同开发开机向导的时候,carry搭建了整个项目的大框架,而我也是相当于第一次参与了一个完整的项目开发。

协同开发期间,发现代码里面充满了框架的味道,各种Present的使用,而我看到了一脸懵逼。在只大概知道Activity怎么使用的人面前,突然像摆出了一本武林秘籍,而此秘籍生涩难懂,但却为我打开了另外一个世界。

经过搜索后,发现这是一种叫做MVP的框架的东西,属于在我们了解的MVC的基础上更好一些的框架。也是几年前的东西了,但作为一个接触android多年的老鸟,开始接触上层的菜鸟来说,需要实践实践把这些东西重新转换为自己的知识。

最近刚好有这么一个练手的机会,当然不能放过,练手的机会是需要开发一个蓝牙和wifi的测试工具。

 

需求很简单:

AndroidTV上需要跑一个apk,此apk需要可以实时监测接入的wifi和蓝牙测试模块板是否正常工作。

正常工作的wifi模块可以搜索到软件设置的wifi ap,信号强度和mac需要不越界等。

蓝牙模块类似,需要可以完整的检测到软件设置的蓝牙设备,mac不越界。

软件可以支持Wifi和蓝牙模块的热插拔重复测试。

软件流程图如下:

MVC模型的缺点:

MVC模型Activity是意义上的View层,但其中操作了control层业务逻辑,并没有做到完全分离,Activity代码太多臃肿,增加了维护、协同开发的难度。

MVP模型的简化图:

MVP模型中将View层和Model数据层完全去耦合,不在发生关联。Presenter作为中间商,承担了更为繁重的任务,所有业务逻辑相关的功能全部都交由Presenter来主导,而View层和Model数据层更多的是被动的接口调用关系。

和View相关的接口全部抽象到IView中,和业务逻辑相关的接口全部抽象到IPresenter中,精简了Activity的繁杂,拿到代码看的话虽然会有些绕,但利于后续功能扩展和维护。

代码整体目录结构

将View相关的目录:ui和view

ui中主要存放了Activity相关的代码。adapter子目录中是Activity中绘制界面时需要加载的listview时自定义的适配器;baseActivity是公共Activity,里面处理了一些公共的功能,如锁屏保功能等。

View中主要存放了自定义的view组件,base子目录存放了一些公共的view。

和数据相关的目录:model

config目录中主要存放了数据实体类,base子目录下是公共的数据实体,BtConfigItemData和WifiCOnfigItemData是蓝牙和wifi相关的数据结构体。

help目录提供了蓝牙和wifi和数据相关的功能,包括数据的获取和保存等。

注意:

虽然View层和Model层在MVP模型中是松耦合的,但是Model层的数据结构体在定义的时候其中包含的属性需要和View可以对应起来。因为自定义的View在刷新的时候需要用到和它相匹配的数据才行,所以Model层的数据结构的定义来源是View的样式和View刷新时需要的数据形式。

控制相关的目录:persenter

presenter中主要存放了具体的业务逻辑相关的操作文件,ISettingPresent是和设置页面触发过来的业务逻辑接口,IDetectPresenter是在检测过程的逻辑接口,有的是从UI中触发而来的,有的是从广播中回调过来的逻辑;impl子目录中主要是这些业务逻辑接口的具体实现。

utils目录:主要存放了一些工具类。

ScreenUtil是在不同分辨率屏幕上的适配的工具类;

SPUtils是Sharepreference轻量级数据存储相关的工具类;

Resource是String字符串资源的动态获取相关的工具类;

L是日志相关的工具类;

Calculate是和数据计算相关的工具类。

common目录:是项目的公共杂项相关

AndroidBroadcast类中主要定义和广播相关的操作;

ConfigConst中定义项目使用的一些常量,包括一些数据常量和自定义的枚举常量等。

api目录:

主要存放了和蓝牙和wifi相关功能接口,对framework中蓝牙和wifi相关接口的功能进行封装供我门项目使用。

MVP中两个关键点:
1、Presenter是持有View和Model的引用的,才可以去更新View和Model层的东西;
2、View中是持有Presenter的引用,所有才能把以前在MVC中交给Activity中控制的动作,转移到Presenter层去实现。

举例说明

1、创建View相关的接口,如刷新View。

public interface IDetectView {
    void refreshWifiView(List<?> list, String mac, WifiCheckResult checkResult);
    void refreshBtView(List<?> list, String mac, BtCheckResult checkResult);
}

2、创建和业务逻辑相关的接口

public interface IDetectPresenter {
    void startDetect();

    void stopDetect();

}

3、Activity中需要去实现View相关的接口,做UI刷新的真正操作;

Activity中想利用presenter来处理逻辑,需要先创建一个presenter的引用,Activity中可以通过持有的presenter接口去调用到逻辑层的接口;

Presenter接口的实现类在构造的时候需要将View的接口对象作为参数传过去,一般是实现view接口的Activity本身;

presenter的实现中根据传过来的view接口参数可以进行view相关接口的调用。

public class DetectActivity extends BaseActivity implements IDetectView{

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

        detectLayout = new DetectLayout(this);
        setContentView(detectLayout);

        //关键操作:将presenter和view关联起来
        detectPresenter = new DetectPresenterImpl(this);
        detectPresenter.startDetect();
    }


    @Override
    public void refreshWifiView(List<?> list, String mac, WifiCheckResult checkResult) {
        L.d("refreshWifiView");    
    }

    @Override
    public void refreshBtView(List<?> list, String mac, ConfigConst.BtCheckResult checkResult) {
        L.d("refreshBtView");
    }
}

4、在DetectPresenterImpl中做业务逻辑接口的实现;

public class DetectPresenterImpl implements IDetectPresenter {

    private IDetectView detectView;
    public DetectPresenterImpl(IDetectView view) {
        //一般是实现IDetectView 接口的Activity对象
        detectView = view;
        //可以拿到model的引用来操作数据
       ......
}

    @Override
    public void startDetect() {

    }

    @Override
    public void stopDetect() {

}

    private void refreshWifiView() {
        detectView.refreshWifiView(wifiResultData, wifiAddr, wifiCheckResult);
    }

    private void refreshBtView() {
        detectView.refreshBtView(btResultList, btMac, btCheckResult);
    }
}

微信公众号:一点微时光
欢迎关注我,一起学习,一起进步!

GitHub源码项目地址:

https://github.com/wenkai520/SkyBtWiFiTestTool

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值