APP下载

基于Flutter的山羊孕测App设计与实现

2023-05-30邵毅何美陈春

电脑知识与技术 2023年3期

邵毅 何美 陈春

关键词:Flutter;Golang;Socket;山羊孕测

中图分类号:TP311 文献标识码:A

文章编号:1009-3044(2023)03-0040-04

随着移动应用在广大群众中的广泛使用频率提高,更多的B端产品逐步转向到移动端,其中原生App 的高性能满足较多场景的使用,随着技术发展,跨平台方案逐步推广,引出众多跨平台技术,如React Native、Weex、Flutter等。2018年谷歌开源Flutter1.0至今3.3 在跨平台的高性能与开发便捷不断受到广泛青睐。本文将在已使用Java SpringBoot设计的山羊孕测管理系统平台的基础上采用Flutter框架开发一套山羊孕测App,实现视频监控、即时通讯、异常通知等功能,为提升与山羊孕测管理系统平台的高性能多线程数据处理能力使用Golang语言开发接口SDK包。有效提高专家、管理员、员工通过App进行对山羊怀孕检测、山羊状态进行监控与管理,使用Flutter进行一套代码开发,编译出原生代码在Android、iOS平台上运行,节省了开发成本,同时也提高了App的运行效率。

1 山羊孕测App 设计

1.1 Flutter 框架介绍

Flutter 是Google 开源的应用开发框架,使用Dart 语言开发,仅需要一套代码就能构建精美的、原生平台编译的多平台应用软件。Flutter可快速直接编译成ARM或者Intel 平台的机械代码,确保拥有原生平台运行的性能表现能力,高效地使用热重载(Hot Reload) 在开发中快速更新实时预览并不丢失状态,在屏幕上,可灵活地将每个像素都由你来把握。在Flutter3.3版本开始逐步引入新的图形引擎: Impeller,提供了丝滑的动画效果,使用Impeller 的应用可以保持60Hz 或者更快的刷新率的同时,能够比以前更进一步地突破界限。Flutter代码由Dart语言编写,该语言提供允许编译为iOS和Android的32位和64位的机械码,以及在Web 允许的JavaScript和桌面设备,并且开源、免费和社区开发者的不断增加,现已被广大开发者使用[1]。

1.2 Go语言介绍

Go语言(Golang) 起源于2007 年,是由Google 的Robert Griesemer,Rob Pike 及Ken Thompson 开发的一门编译型语言。具有部署简单、并发性能好、设计与执行能力好、支持垃圾回收功能、跨平台编译运行等优点。具有Gomobile是一个应用于iOS和Android 的优秀跨平台开发库,为开发者提供创建Android或iOS移动平台代码的工具。

1.3 山羊孕测设计

针对性能与降低开发成本,Flutter具有较好的状态管理以及极快的UI便捷开发与跨平台的支持。在实时数据更新与数据接口请求,考虑到高并发、跨平台、低成本开发[2],使用Socket连接,实时进行数据通信触发数据更新接口下发更新通知,从性能方面考虑,选择使用Go语言进行编写后端与App之间数据交互的桥梁,编译出与后端数据交互的SDK,方便在多场景下集成使用[3]。并使用Flutter 提供Method?Channel通信方式,在Native和Flutter的进行调用原生的代码。其中用到状态管理插件在Provider、GetX、Bloc、Redux中从难易度上考虑,其中Provider的使用简便,但是它需要更多的框架搭建与处理全局上下文的问题,因此选择GetX状态管理,它的使用简单,并对全局context上下文提供了对应的方法,在业务逻辑中方便地调用以及对各个页面之间进行跨页面的状态更新。避免过多重复的Widget 组件实现,对重复使用频率高的组件进行封装,提高了代码质量,方便在各个页面之间直接调用,避免重复UI 逻辑实现,并针对重复调用方法逻辑进行封装到统一的Controller 控制器中由GetX状态管理方便调用,提高了代码阅读性[4]。

1.4 山羊孕测App网络请求拓扑图

山羊孕测App首次启动进行登录,向后端发送请求,通过网关授权后从后端应用服务器获取数据信息进行初始化SDK接口并建立Socket 连接,监听数据更新。当触发监控页面时连接视频监控视频推流地址呈现画面在App,所有数据通过SDK进行发起数据请求返回到App呈现数据。在避免重复的登录操作,使用了无状态Token 校验权限,在每个请求中均携带Token请求,后端服务校验通过后,返回数据[5]。图1为网络请求拓扑图。

1.5 山羊孕测App 功能

山羊孕测App底部导航主要划分为首页、资讯、消息、我的四个主要页面入口。首页:包含山羊数据列表,每个山羊可点击查看具体基本信息、其他观察、超声波、预警推送、生物激素、专家意见、视频监控、当日事件等功能。资讯:提供相关的资讯内容阅读。消息:为增强即时通讯能力,用于专家、员工、管理员之间的消息即时沟通能力。我的:提供个人信息资料修改,管理员可对用户和山羊信息进行管理维护,功能结构如图2-①。除消息页面(即时通讯)为通用功能、资讯页面与我的页面个人信息修改外,在登录页面可以通过申请账号功能页面申请账号、忘记密码、登录账号三项功能,在登录成功后根据申请账号时申请的角色权限不同将功能细分:管理员拥有管理后台、推送版本、修改参数功能,专家与员工角色同时具备查看信息、查看监控、推送预警、日历事件,专家额外拥有编辑建议、推送状态功能权限,员工额外拥有上传图片权限。如图2-②所示。

2 山羊孕测实现与关键技术

2.1 服务端与App端数据交互

Flutter编写App在进行数据交互时候,需要与后端业务通过API接口与Socket通道进行交互。在本App设计中使用Golang对后端业务接口进行封装成SDK API,Flutter需要进行SDK初始化后端接口地址,通过调用接口与后端进行交互,并使用SDK初始化Socket建立連接,实时更新山羊状态数据,通过GetX 状态管理对UI状态更新。

2.2 App 页面功能实现[6]

图3为山羊孕测App实现部分页面图,详情见下:

1) 底部导航:使用自定义BuildNavigation底部导航组件传入Scaffold 脚手架的bottomNavigationBar 生成底部导航,在脚手架body中使用IndexedStack组件记录当前导航索引进行切换页面,效果如图3-① 所示。

2) 首页:使用GetX中Controller控制器初始化数据并建立Socket连接监听数据变化,关键代码如下:

initSocket() async {

var socket = await Socket.connect(Api.socket, Api.

socketPort);

socket.listen((event) {

initAllSheepData();

update(['MainMHO']);

});

使用card_swiper插件完成轮播组件,选项卡区域使用TabBar组件实现,效果如图3-②所示,选项卡中数据使用GetBuilder定义id并包裹ListView列表组件加载山羊数据,在监听数据变化时,通过GetX中up?date()方法传入定义id值进行局部组件更新。

在点击每个山羊详情卡片式组件进入详情页面时候,优先进行权限校验,根据权限不同,所使用的功能权限不同。在无权限时将提示无权访问弹窗并返回至首页。所有按钮使用GestureDetector与Container 进行封装成可自定义颜色、图片、内容的Widget组件,避免过多重复代码编写。员工使用确定怀孕与取消确定触发Socket发送广播通知其他在线用户状态更新,关键代码如下:

putDescribe(int id, String msg) {

Get.back();

SheepApi.putSheep({

"sheepId": id,

"sheepDescribe": msg,

}).then((value) {

initSheepData(state. sheepModel. value. data!.

sheepId!);

});

包含了生物激素,超聲波,其他观察,运动,温度,日历,智慧耳标,视频监控,AI助手、当日记事,预警推送、取消预警,专家意见。点击进入“生物激素,超声波,其他观察,运动,温度,日历,智慧耳标,视频监控”可以进入功能详情页查看信息执行相关操作。通过各指标信息的查看,管理员点击进入“预警推送、取消预警”可以对山羊是否怀孕进行预警和撤销。点击进入“专家意见”可以查看专家给的相关意见,但不能修改。点击进入“AI助手”,可为将来AI功能提供扩展接口。点击进入“当日记事”,可在日历记录当日山羊情况[7],效果如图3-③所示。

专家登录时,可对专家意见中内容进行编辑,内容编辑使用flutter_quill富文本插件实现,员工只能进行查看内容不可编辑,效果如图3-④ 所示。

运动与温度数据通过调用后端接口获取传感器数据得到当天每半小时的数据[8]。其中日历部分使用bruno 插件完成UI功能,并可通过当日记事按钮提交当日事件记录。关键代码如下:

changeDateTime(DateTime date?Time) {

String calendarDate = ' ${dateTime.

year} - ${dateTime. month} - ${dateTime.

day}';

CalendarApi.getCalendarByDate(

Get. arguments['sheepId']. toString(),

calendarDate, '1')

.then((value) {

state. listCalendarModel. value =

value.data!;

});

}

void postCalendar() {

var date = DateTime.now();

String calendarDate = '${date.year}-${date.month}-

${date.day}';

CalendarApi.postCalendar(

Get.arguments.toString(),

calendarDate,

'1',

'山羊状况记录: ${state.text}',

).then((value) {

if (value.data!.code == 20000) {

contextFocusNode.unfocus();

Get.dialog(

ShowLoading(

text: '${value.data!.msg}',

),

).then((value) {

Get.back();

});

}

});

}

视频监控页面在完成后端数据鉴权后获取到监控视频推流地址,路由并携带推流地址到视频播放页面,通过调用better_player插件初始化后,视频进行加载播放,在返回页面时候销毁播放器避免视频常驻后台播放占用内存与带宽占用,关键代码如下:

AspectRatio(

aspectRatio: 16 / 9,

child: BetterPlayer.network(

Get.arguments,

betterPlayerConfiguration: const BetterPlayerCon?

figuration(

autoPlay: true,

aspectRatio: 16 / 9,

),

)3) 资讯:通过调用封装的SDK接口,请求资讯数据,效果如图3-⑤所示。初始加载20条数据并在滑动页面最后一条数据时触发加载更多数据,每次触发加载递增20条数据,关键代码如下:

void initNewsData() {

NewsApi. getPageNews(current: current, pageSize:

pageSize).then((value) {

state.listNewsModel.value = value.data!;

});

}4) 消息:为了方便工作人员之间的及时的沟通处理能力,集成tim_ui_kit插件,完成简单的即时通讯功能业务能力[9],效果如图3-⑥所示。关键代码如下:

initTencentIMSdk() {

_coreInstance.init(

sdkAppID: Config.sdkAppID,

loglevel: LogLevelEnum.V2TIM_LOG_DEBUG,

listener: V2TimSDKListener());

}

final MessageState state = MessageState();

final TIMUIKitConversationController controller =

TIMUIKitConversationController();

@override

void onInit() async {

super.onInit();

controller.loadData();

controller.setConversationListener(

listener: V2TimConversationListener(

onNewConversation: (conv) {

update();

},

onConversationChanged: (conv) {

update();

},

),

);

}5) 我的:調用封装的SDK获取个人信息后,通过个人信息中指定角色判断,管理将额外显示用户管理、山羊管理入口按钮,效果如上图3-⑦所示。关键代码如下:

void updateUserInfo() {

String? faceUrl;

if (state.faceUrl.value != '') {

faceUrl = state.faceUrl.value;

}

UserApi.updateUserInfo(

state.userInfo.value.data!.userId!,

faceUrl!,

nicknameController!.text,

emailController!.text,

).then((value) async {

// 更新IM头像

V2TimUserFullInfo userFullInfo = V2TimUserFull?

Info();

userFullInfo. userID = state. userInfo. value. data!.

username;

userFullInfo.faceUrl = Api.baseUrl + faceUrl!;

userFullInfo.nickName =

nicknameController!. text ! = '' ? nicknameCon?

troller!.text : '';

V2TimCallback v2timCallback = await TIMUIKit?

Core.getSDKInstance()

.setSelfInfo(userFullInfo: userFullInfo);

if (v2timCallback.code == 0) {

iniUserInfo();

Get.back();

}

});

}

3 性能效果分析

通过Android Studio 的Flutter 插件提供的FlutterInspector进行调试观察FPS浮动情况,得到一个良好的效果,均保持在60FPS左右的范围,如图3-⑧所示。通过校内学生100人在多种不同机型的安装下使用,对山羊孕测App进行多个页面的高频率反复随机点击操作和查看各种功能,无任何闪退情况,各项功能正常。Socket连接中无断连,并均能收到实时数据更新提示,消息的互发及时沟通无任何数据丢失。

4 结束语

山羊孕测App的开发,通过对业务框架设计,将业务逻辑、UI、数据分离设计开发,降低耦合性,对各项传感器的高性能连接,保障了产品业务的高可用性。通过Flutter与Go语言的跨平台特性节省了开发成本。