授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷

一、你如果想学基于Arduino的ESP8266开发技术

一、基础篇

  1. ESP8266开发之旅 基础篇① 走进ESP8266的世界
  2. ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境
  3. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明
  4. ESP8266开发之旅 基础篇④ ESP8266与EEPROM
  5. ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
  6. ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库

二、网络篇

  1. ESP8266开发之旅 网络篇① 认识一下Arduino Core For ESP8266
  2. ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库
  3. ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
  4. ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
  5. ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
  6. ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库
  7. ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
  8. ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
  9. ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
  10. ESP8266开发之旅 网络篇⑩ UDP服务
  11. ESP8266开发之旅 网络篇⑪ WebServer——ESP8266WebServer库的使用
  12. ESP8266开发之旅 网络篇⑫ 域名服务——ESP8266mDNS库
  13. ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 Flash文件系统
  14. ESP8266开发之旅 网络篇⑭ web配网
  15. ESP8266开发之旅 网络篇⑮ 真正的域名服务——DNSServer
  16. ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新

三、应用篇

  1. ESP8266开发之旅 应用篇① 局域网应用 ——炫酷RGB彩灯
  2. ESP8266开发之旅 应用篇② OLED显示天气屏
  3. ESP8266开发之旅 应用篇③ 简易版WiFi小车

四、高级篇

  1. ESP8266开发之旅 进阶篇① 代码优化 —— ESP8266内存管理
  2. ESP8266开发之旅 进阶篇② 闲聊Arduino IDE For ESP8266配置
  3. ESP8266开发之旅 进阶篇③ 闲聊 ESP8266 Flash
  4. ESP8266开发之旅 进阶篇④ 常见问题 —— 解决困扰
  5. ESP8266开发之旅 进阶篇⑤ 代码规范 —— 像写文章一样优美
  6. ESP8266开发之旅 进阶篇⑥ ESP-specific APIs说明

1.前言

    在上一篇博文 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制 中,博主提供了OneNet智能灯的Mqtt协议的配套App。那么,为了方便大家开发以及拓展,博主这里简述一下源码设计。

2.源码下载

  • 请到博主技术交流群群文件下载:

3.源码分析

3.1 App开发工具

  • Android Studio,官方认证工具,请自行配置好Java环境以及AS工具,目前博主属于最新版本。

3.2 代码整体结构

  • 把上面下载下来的源码导入Android Studio之后,可以看到如下结构:

    博主这里为了开发方便,分出了三个module:
  • app_common,常用公共模块,比如各种工具类(打印日志工具,时间格式转换工具)
  • app_ormlib,数据库服务(这里没有用到,为了后面拓展预留)
  • app_widget,常用UI,基础组件,包括封装基础activity类,recyclerview,以及我广泛应用的mvp设计框架
  • app:这里就是我们主要的业务代码。

3.3 MVP框架解析

  • 至于什么叫做MVP,博主这里不讲,请自行百度。以下代码构成了MVP的主体框架:

    Model:专注于处理数据
    View:专注于页面显示
    Presenter:协调Model和View的调用关系
  • 接下来,看基于MVP架构的业务代码:

    通过名字就可以快速知道对应的具体业务:
  • 配置MQTT页面:OneNetConfigXXXX
  • 列表主页面:MainXXXXX
  • 关于应用页面:AboutMeXXXX
  • 拓展页面:XXXXXXX

接下来,我们挑一个页面来讲解,方便大家了解MVP工作方式。

3.4 Main控制主页面解析

3.4.1 MVP协议

/**
 * mvp 主页面协议 presenter层
 */
public interface IMainContract {
    // model层
    interface IMainModel extends IBaseModel {
        void loadData(Context context, ICallBack<List<OneNetDeviceModel>> callBack);
        void updateDeviceDetail(Context context,OneNetDeviceModel model, ICallBack<String> callBack);
    }
    //view层
    interface IMainView extends IBaseView {
        void showLoading(String loadmsg);
        void dismissLoading(OnDismissCallbackListener callback);
        void refreshList(List<OneNetDeviceModel> list);
    }
}

3.4.2 Model层-数据处理

  • 我们关注Main相关的代码:
public class MainModel implements IMainContract.IMainModel {

    SimpleTask task;
    //获取设备列表
    @Override
    public void loadData(Context context, final ICallBack<List<OneNetDeviceModel>> callBack) {

        if(task != null && task.getStatus()== AsyncTask.Status.RUNNING){
            task.cancel(true);
        }
        task = new SimpleTask() {

            GetOneNetDeviceListEntity entity;

            @Override
            protected void onPreExecute() {
                entity = new GetOneNetDeviceListEntity();
            }

            @Override
            protected Object doInBackground(String... strings) {
                return entity.request();
            }

            @Override
            protected void onPostExecute(Object o) {
                String result = (String) o;
                if("200".equals(result)){
                   if(entity.data != null && entity.data.devices.size()!=0) {
                       List<OneNetDeviceModel> list = new ArrayList<>();
                       for(OneNetDeviceModel model:entity.data.devices){
                           if(!model.getId().equals(PreferenceUtil.getInstance().getDeviceId())){
                               list.add(model);
                           }
                       }

                       callBack.onSuccess(list);
                   }
                }else {
                    callBack.onFaild(result);
                }
            }
        };
        task.startTask();
    }

//更新设备信息
    @Override
    public void updateDeviceDetail(Context context, final OneNetDeviceModel model, final ICallBack<String> callBack) {
        if(task != null && task.getStatus()== AsyncTask.Status.RUNNING){
            task.cancel(true);
        }
        task = new SimpleTask() {

            UpdateOneNetDeviceDetailEntity entity;

            @Override
            protected void onPreExecute() {
                entity = new UpdateOneNetDeviceDetailEntity(model.getId());
            }

            @Override
            protected Object doInBackground(String... strings) {
                return entity.request(model);
            }

            @Override
            protected void onPostExecute(Object o) {
                String result = (String) o;
                if("200".equals(result)){
                    callBack.onSuccess("更新成功");
                }else {
                    callBack.onFaild(result);
                }
            }
        };
        task.startTask();
    }
}

3.4.3 View层-UI处理

/**
 * @author wty
 * @Description 控制页面
 **/
public class MainActivity extends BaseActivity<MainPresenter> implements IMainContract.IMainView {

    @Bind(R.id.listview)
    XRecyclerView listview;

    DeviceListAdapter adapter;

    public static void startActivity(Activity activity) {
        Intent intent = new Intent(activity, MainActivity.class);
        activity.startActivity(intent);
    }

    @Override
    public MainPresenter getPresenter() {
        return new MainPresenter();
    }

    @Override
    public void onInitView(Bundle savedInstanceState) {
        /**
         * 第一个参数是服务器地址
         * 第二个参数是用户名
         * 第三个参数是密码
         * 第四个参数是客户端ID
         * 第五个参数是主题
         **/
        MqttManager
                .getInstance()
                .creatConnect(
                        AppConstant.RequestUrl.ONENET_MQTT,
                        PreferenceUtil.getInstance().getProductId(),
                        PreferenceUtil.getInstance().getApiKey(),
                        PreferenceUtil.getInstance().getDeviceId(),
                        "esp8266");

        getDefaultNavigation().setTitle("OneNet智能灯");
        getDefaultNavigation().getLeftButton().setButton("配置", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                OneNetMqttConfigActivity.startActivity(MainActivity.this);
                finish();
            }
        });
        getDefaultNavigation().getRightButton().setButton("关于应用", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AboutActivity.startActivity(MainActivity.this);
            }
        });

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        listview.setLayoutManager(layoutManager);
        listview.setPullRefreshEnabled(false);
        listview.setLoadingMoreEnabled(false);
        List<OneNetDeviceModel> data = new ArrayList<>();
        adapter = new DeviceListAdapter(this,data,mPresenter);
        listview.setAdapter(adapter);

        mPresenter.refreshList(MainActivity.this);
    }

    @Override
    protected boolean isEnableStatusBar() {
        return true;
    }

    @Override
    protected List<String> validate() {
        List<String> list = super.validate();
        return list;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MqttManager.release();
    }

    @Override
    public int getLayoutResource() {
        return R.layout.activity_main;
    }

    @Override
    public void refreshList(List<OneNetDeviceModel> list) {
        adapter.retsetData(list);
    }
}

3.4.4 Presenter层-中间协调层

/**
 * 主页面 presenter
 */
public class MainPresenter extends BasePresenter<IMainContract.IMainView> {

    private IMainContract.IMainModel mMainModel;

    public MainPresenter(){
        mMainModel = new MainModel();
    }

    public void refreshList(Context context){
        mView.showLoading("获取设备列表中...");

        mMainModel.loadData(context, new ICallBack<List<OneNetDeviceModel>>() {
            @Override
            public void onSuccess(final List<OneNetDeviceModel> list) {
                mView.refreshList(list);
                mView.dismissLoading();
            }

            @Override
            public void onFaild(String msg) {
                mView.dismissLoading(new OnDismissCallbackListener(msg, SweetAlertDialog.ERROR_TYPE));
            }
        });
    }

    public void updateDeviceDetail(final Context context, OneNetDeviceModel model){
        mView.showLoading("更新设备信息中...");

        mMainModel.updateDeviceDetail(context,model, new ICallBack<String>() {
            @Override
            public void onSuccess(final String result) {
                mView.dismissLoading();
                refreshList(context);
            }

            @Override
            public void onFaild(String msg) {
                mView.dismissLoading(new OnDismissCallbackListener(msg, SweetAlertDialog.ERROR_TYPE));
            }
        });
    }
}

基本上,每个页面都是按照这个MVP的设计思路去分析就可以了,非常简单。

4.总结

一句话,高手勿喷。

玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架的更多相关文章

  1. 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  2. 玩转OneNET物联网平台之MQTT服务③ —— 远程控制LED(设备自注册)

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  3. 玩转OneNET物联网平台之MQTT服务② —— 远程控制LED

    1.理论基础     参考博主线上博文: 玩转PubSubClient MQTT库 玩转OneNET物联网平台之简介 玩转OneNET物联网平台之MQTT服务① 2.远程控制LED 2.1 实验材料 ...

  4. 玩转OneNET物联网平台之MQTT服务⑦ —— 远程控制LED(数量无限制)+ Android App控制 优化第一版

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  5. 玩转OneNET物联网平台之HTTP服务③ —— OneNet智能灯 HTTP版本

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  6. 玩转OneNET物联网平台之MQTT服务① —— OneNetMqtt全方位调试

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  7. 玩转OneNET物联网平台之HTTP服务① —— 模拟上传温度(TcpClient)

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  8. 玩转OneNET物联网平台之简介

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  9. HelloX操作系统与中国移动OneNET物联网平台成功完成对接

    HelloX成功与中国移动物联网平台对接 经过HelloX项目组同仁的努力,尤其是Tywin(@飓风)的努力下,HelloX最新版本V1.78已成功与中国移动OneNET(open.iot.10086 ...

随机推荐

  1. Spring——依赖注入(DI)详解

    声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...

  2. [翻译] ASP.NET Core 3.0 的新增功能

    ASP.NET Core 3.0 的新增功能 全文翻译自微软官方文档英文版 What's new in ASP.NET Core 3.0 本文重点介绍了 ASP.NET Core 3.0 中最重要的更 ...

  3. Docker学习之docker常用命令

    docker ps -a 表示所有容器 docker pull 获取image docker build 创建image docker run 运行container docker images 列出 ...

  4. DW网页代码笔记

    DW网页代码笔记 1.样式.       class  插入类样式  标签技术(html)解决页面的内容样式技术(css)解决页面的外观脚本技术       解决页面动态交互问题<form> ...

  5. Webpack配置区分开发环境和生产环境

    在项目开发的时候,我们通常会将程序分为开发环境和生产环境(或者叫线上环境),开发环境通常指的是我们正在开发的这个阶段所需要的一些环境配置,也就是方便我们开发人员调试开发的一种环境:生产环境通常指的是我 ...

  6. Dubbo源码解析(一)服务发现

    一.Dubbo源码模块 官网地址 源码地址 1.1 源码模块组织 Dubbo工程是一个Maven多Module的项目,以包结构来组织各个模块. 核心模块及其关系,如图所示: 1.2 模块说明 dubb ...

  7. Oracle 的 rownum 问题

    对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=),并非说用>,>=,=,be ...

  8. vue-cli 脚手架安装

    1.安装node;选择适合自己系统的文件,下载一路next , a安装成功后,打开运行输入cmd 进入命令行: 在命令行工具中输入 npm -v  检查版本号 如果出现 则安装成功:(npm为node ...

  9. 【柠檬班】jmeter 不写代码,秒秒钟提取动态列表最后一个值

    在用jmeter做接口测试时,我们经常会遇到,一个接口返回一个json串,在这个json串中,某个节点的值是一个列表,而且这个列表的长度是动态变化的.如:   获取用户列表,用户信息是个列表,类似的接 ...

  10. Linux 下复制整个文件夹的命令

    在 Linux 下复制整个文件夹,包括它的子文件夹及其隐藏文件的方法是: cp -r /etc/skel /home/user 或者 mkdir /home/<new_user> cp - ...