玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。
QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷
一、你如果想学基于Arduino的ESP8266开发技术
一、基础篇
二、网络篇
- ESP8266开发之旅 网络篇① 认识一下Arduino Core For ESP8266
- ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库
- ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
- ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
- ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
- ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库
- ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
- ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
- ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
- ESP8266开发之旅 网络篇⑩ UDP服务
- ESP8266开发之旅 网络篇⑪ WebServer——ESP8266WebServer库的使用
- ESP8266开发之旅 网络篇⑫ 域名服务——ESP8266mDNS库
- ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 Flash文件系统
- ESP8266开发之旅 网络篇⑭ web配网
- ESP8266开发之旅 网络篇⑮ 真正的域名服务——DNSServer
- ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新
三、应用篇
四、高级篇
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框架的更多相关文章
- 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务③ —— 远程控制LED(设备自注册)
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务② —— 远程控制LED
1.理论基础 参考博主线上博文: 玩转PubSubClient MQTT库 玩转OneNET物联网平台之简介 玩转OneNET物联网平台之MQTT服务① 2.远程控制LED 2.1 实验材料 ...
- 玩转OneNET物联网平台之MQTT服务⑦ —— 远程控制LED(数量无限制)+ Android App控制 优化第一版
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之HTTP服务③ —— OneNet智能灯 HTTP版本
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务① —— OneNetMqtt全方位调试
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之HTTP服务① —— 模拟上传温度(TcpClient)
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之简介
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- HelloX操作系统与中国移动OneNET物联网平台成功完成对接
HelloX成功与中国移动物联网平台对接 经过HelloX项目组同仁的努力,尤其是Tywin(@飓风)的努力下,HelloX最新版本V1.78已成功与中国移动OneNET(open.iot.10086 ...
随机推荐
- AtCoder从小白到大神的进阶攻略
前言 现在全球最大的编程比赛记分网站非CodeForces和AtCoder莫属了,@ezoixx130大佬已经在去年介绍过CodeForces了(传送门),那么现在我们主要谈一下AtCoder. 简介 ...
- mysql创建表时字段类型选择与优化
一.选择原则 1.应该尽量使用可以正确存储数据的最小字段类型 2.选用简单的数据类型,例如:一个是尽量用mysql内置的字段类型来存储日期和时间:另一个存储IP地址尽量用整型:能用整型的尽量不用字符串 ...
- 连接电脑时,无法启用USB调试
原因: 手机悬浮球 解决方案: 取消悬浮球,停止一切悬浮应用 (下面的废话可以不听) 预置条件: 手机已经打开开发者模式 开启USB调试模式 电脑能检测到手机 故事背景: 经常用手机连接电脑进行adb ...
- setInterval、setTimeout之遗忘的第三个参数
今天看阮一峰老师的ES6入门,在一个关于promise的小demo里,老师用到了setTimeout的第三个参数,惊了有没有,定时器还有第三个参数? 喏就是下面这个demo: function tim ...
- 基于Babylon.js编写宇宙飞船模拟程序1——程序基础结构、物理引擎使用、三维罗盘
计划做一个宇宙飞船模拟程序,首先做一些技术准备. 可以访问https://ljzc002.github.io/test/Spacetest/HTML/PAGE/spacetestwp2.html查看测 ...
- Android导入Burp Suite证书抓包HTTPS
需求 Android APP安全测试时,主要工作分为: APK安全 业务安全 APK安全这里不讨论,我说说业务安全,因为大部分的业务校验逻辑还是放在Servier端,这里就会涉及到网络通信了.因此网络 ...
- Maven 梳理-手动创建Maven项目(非web),使用Maven编译、测试、打包、安装、引用
创建空目录 F:\jtDevelop\maventest\myapp 创建pom.xml文件 <project xmlns="http://maven.apache.org/POM/4 ...
- Spring 梳理-启用MVC
启用注解启动的Spring MVC xml <mvc:annotation-dirven> <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置 ...
- 每个人都要学的图片压缩终极奥义,有效解决 Android 程序 OOM
# 由来 在我们编写 Android 程序的时候,几乎永远逃避不了图片压缩的难题.除了应用图标之外,我们所要显示的图片基本上只有两个来源: 来自网络下载 本地相册中加载 不管是网上下载下来的也好,还是 ...
- SpringBootSecurity学习(12)前后端分离版之简单登录
前后端分离 前面讨论了springboot下security很多常用的功能,其它的功能建议参考官方文档学习.网页版登录的形式现在已经不是最流行的了,最流行的是前后端分离的登录方式,前端单独成为一个项目 ...