玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架
- 2019 年 10 月 29 日
- 笔记
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。
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.总结
一句话,高手勿喷。