邵毅 何美 陳春


關鍵詞: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語言的跨平臺特性節省了開發成本。