玩转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 ...
随机推荐
- BOM之本地数据存储
JavaScript中本地存储数据常用的,且兼容性较好的有两种方式,cookie和Storage.另外还可以使用location.hash临时存储少量关键信息. 一 location.hash ...
- 【linux】【sonarqube】安装sonarqube7.9
前言 SonarQube 是一款用于代码质量管理的开源工具,它主要用于管理源代码的质量. 通过插件形式,可以支持众多计算机语言,比如 java, C#, go,C/C++, PL/SQL, Cobol ...
- Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码
在文章:Mybatis源码解析,一步一步从浅入深(一):创建准备工程,中我们为了解析mybatis源码创建了一个mybatis的简单工程(源码已上传github,链接在文章末尾),并实现了一个查询功能 ...
- python 数据分析师
简介 越来越多的政府机关.企事业单位将选择拥有数据分析师资质的专业人士为他们的项目做出科学.合理的分析.以便正确决策:越来越多的风险投资机构把数据分析师所出具的数据分析报告作为其判断项目是否可行及是否 ...
- Linux 部署vsftp服务及详解
一.FTP服务概述: FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务. FTP(File Transf ...
- C#2匿名方法中的捕获变量
乍一接触"匿名方法中的捕获变量"这一术语可能会优点蒙,那什么是"匿名方法中的捕获变量"呢?在章节未开始之前,我们先定义一个委托:public delegate ...
- Go标准库Context
在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理.请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务.用来处理一个请 ...
- postgres 数据库 citus 集群分片
前言 什么时候需要考虑做数据切分? 1.能不切分尽量不要切分 并不是所有表都需要进行切分,主要还是看数据的增长速度.切分后会在某种程度上提升业务的复杂度,数据库除了承载数据的存储和查询外,协助业务更好 ...
- 软件开发工具(第12章: CVS的安装及使用)
一.CVS介绍 并发版本系统(Concurrent Versions System——CVS)是一个常用 的代码版本控制系统. 使用CVS可以对代码进行集中管理,记录代码所有的更改历史,提供 协作开发 ...
- sprigboot项目中配置xml格式的logback
slf4j依赖和logback的依赖 idea中springboot项目的resources目录下新建logback-spring.xml文件,内容大致如下: <?xml version=&qu ...