楊道全



摘要:該文基于App Inventor系統(tǒng),運(yùn)用 MQTT 即時(shí)通信技術(shù),設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)能夠多人協(xié)作繪畫(huà)的手機(jī)應(yīng)用。在教學(xué)實(shí)踐中,由于App Inventor系統(tǒng)不要求學(xué)生先學(xué)習(xí)編程語(yǔ)法就能開(kāi)始編程,極大地降低編程門(mén)檻。通過(guò)講解該實(shí)例的開(kāi)發(fā),對(duì)培養(yǎng)學(xué)生的編程興趣,增強(qiáng)學(xué)生對(duì)網(wǎng)絡(luò)通信技術(shù)的理解有較好的效果。
關(guān)鍵詞:圖形化編程;App Inventor;畫(huà)板;MQTT
中圖分類(lèi)號(hào):TP319? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2022)16-0097-03
1 引言
智能手機(jī)的普及,各種各樣的手機(jī)應(yīng)用滲透到使用者的工作和生活中。盡管如此,智能手機(jī)的用戶(hù)仍時(shí)常找不到合適使用的手機(jī)應(yīng)用,想要自己開(kāi)發(fā)卻苦于沒(méi)有掌握編程技術(shù)。“App Inventor的出現(xiàn)旨在普及手機(jī)應(yīng)用開(kāi)發(fā)技術(shù),并在各種教育環(huán)境中用作學(xué)習(xí)計(jì)算思維的工具,教人們構(gòu)建應(yīng)用程序以解決工作與生活中的問(wèn)題,讓普通人也能開(kāi)發(fā)屬于自己的手機(jī)應(yīng)用。”[1-2]本文基于App Inventor系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)的手機(jī)應(yīng)用,為編程愛(ài)好者和計(jì)算思維教學(xué)提供參考。
2 相關(guān)技術(shù)
2.1 App Inventor技術(shù)簡(jiǎn)介
“App Inventor是一個(gè)直觀的可視化編程環(huán)境,允許每個(gè)人為 Android 手機(jī)、iPhone 和 Android/iOS 平板電腦構(gòu)建功能齊全的應(yīng)用程序。那些剛接觸App Inventor的人,可以在 30 分鐘內(nèi)完成第一個(gè)簡(jiǎn)單應(yīng)用程序的制作。App Inventor項(xiàng)目旨在幫助所有人,尤其是年輕人,從技術(shù)消費(fèi)轉(zhuǎn)向技術(shù)創(chuàng)造,從而實(shí)現(xiàn)軟件開(kāi)發(fā)的普及化。”[3]截至本文完稿時(shí),App Inventor支持 iPhone(iOS)應(yīng)用的功能尚未開(kāi)發(fā)完成,還未在官方服務(wù)器[4]上線(xiàn)。
App Inventor基于 Apache2 協(xié)議開(kāi)源,因此在國(guó)內(nèi)外有很多個(gè)分支版本,本文選用的是國(guó)內(nèi)的 WxBit 圖形化編程系統(tǒng)。該版本針對(duì)國(guó)內(nèi)用戶(hù)做了大量本地化的開(kāi)發(fā)工作,支持多點(diǎn)觸控并且提供MQTT客戶(hù)端組件,支持多人同時(shí)連接調(diào)試和跨網(wǎng)段調(diào)試,對(duì)使用者更加友好,也更加適合用于網(wǎng)絡(luò)教學(xué)。
2.2 MQTT技術(shù)簡(jiǎn)介
MQTT(Message Queuing Telemetry Transport,消息隊(duì)列遙測(cè)傳輸協(xié)議)由 IBM 在1999年發(fā)布,構(gòu)建于 TCP/IP 協(xié)議之上,是一種基于發(fā)布/訂閱模式的輕量級(jí)二進(jìn)制網(wǎng)絡(luò)通信協(xié)議。由于 MQTT 協(xié)議靈活的訂閱機(jī)制、服務(wù)質(zhì)量(Quality of Service)、遺愿消息(Will Message)等特性,適用于低帶寬、不可靠的網(wǎng)絡(luò)下提供實(shí)時(shí)可靠的消息服務(wù),使其在物聯(lián)網(wǎng)、小型設(shè)備、移動(dòng)應(yīng)用等方面有廣泛的應(yīng)用[5]。MQTT 的訂閱模式如圖1所示。
3 系統(tǒng)設(shè)計(jì)
3.1 啟動(dòng)界面設(shè)計(jì)
本文設(shè)計(jì)的多人協(xié)作繪畫(huà)板,允許多位安裝該應(yīng)用的用戶(hù)同時(shí)繪畫(huà),每一位用戶(hù)所繪制的圖畫(huà),即時(shí)在其他用戶(hù)的畫(huà)板中顯示。在應(yīng)用啟動(dòng)時(shí)要求用戶(hù)填寫(xiě)畫(huà)板名稱(chēng),只有使用相同名稱(chēng)畫(huà)板的用戶(hù),才能在一起繪畫(huà),這樣能夠避免多人同時(shí)使用該應(yīng)用時(shí)造成混亂。原型設(shè)計(jì)如圖2所示。
3.2 繪畫(huà)界面設(shè)計(jì)
用戶(hù)填寫(xiě)畫(huà)板名稱(chēng)進(jìn)入后,即可開(kāi)始繪畫(huà)。默認(rèn)選中黑色的畫(huà)筆,用戶(hù)手指按在屏幕上移動(dòng),移動(dòng)的軌跡連接起來(lái),就是所畫(huà)出的線(xiàn)條。允許多個(gè)手指同時(shí)按在屏幕上繪畫(huà),以便用戶(hù)可以快捷畫(huà)出多層的線(xiàn)條或其他特殊的效果。應(yīng)用根據(jù)手指按在屏幕的順序給予編號(hào),可以為每個(gè)序號(hào)的手指設(shè)置不同的畫(huà)筆粗細(xì)和顏色。原型設(shè)計(jì)如圖3所示。
3.3 協(xié)作設(shè)計(jì)
用戶(hù)輸入畫(huà)板名稱(chēng)開(kāi)始繪畫(huà),實(shí)際就是向MQTT Broker發(fā)布和訂閱畫(huà)板名稱(chēng)設(shè)置的主題。當(dāng)用戶(hù)手指(觸控點(diǎn))在屏幕移動(dòng)時(shí),應(yīng)用將接收到的屏幕坐標(biāo)發(fā)送到該主題,本應(yīng)用和其他使用相同主題的應(yīng)用都會(huì)接收到坐標(biāo)消息。考慮到教學(xué)所需的可讀性,坐標(biāo)消息設(shè)計(jì)為JSON文本,數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)如下:
{"id":"client1","paths":{"1":{"size":1,"color":-16777216,"points":[[12,10],[14,20],[20,30],[22,43]]},"2":{"size":2,"color":-20561,"points":[[100,80],[90,90],[93,95],[93,124],[99,135]]}}}
id:繪畫(huà)板的標(biāo)識(shí),也是MQTT客戶(hù)端的標(biāo)識(shí),用于區(qū)分消息來(lái)源。
paths:筆畫(huà)記錄,對(duì)應(yīng)觸控點(diǎn)的移動(dòng)軌跡。
size:畫(huà)筆的粗細(xì),單位為dp(Density-independent Pixels)。
color:畫(huà)筆的顏色,為ARGB表示顏色對(duì)應(yīng)的整數(shù)值。
points:筆畫(huà)的坐標(biāo)點(diǎn),記錄觸控點(diǎn)依次經(jīng)過(guò)的屏幕坐標(biāo)。
4 系統(tǒng)實(shí)現(xiàn)
打開(kāi)瀏覽器登錄 WxBit 圖形化編程系統(tǒng),新建一個(gè)名稱(chēng)為“多人協(xié)作繪畫(huà)板v1”的項(xiàng)目開(kāi)始制作。創(chuàng)建項(xiàng)目完成后自動(dòng)進(jìn)入編程界面,在項(xiàng)目名稱(chēng)條的右邊有2個(gè)按鈕,代表系統(tǒng)的兩種視圖:組件設(shè)計(jì)和邏輯設(shè)計(jì)。在組件設(shè)計(jì)視圖中擺放好使用到的組件,再切換到邏輯設(shè)計(jì)視圖完成圖形化編程。
4.1 啟動(dòng)界面的組件設(shè)計(jì)
按照設(shè)計(jì),在開(kāi)始繪畫(huà)前,需要用戶(hù)填寫(xiě)繪畫(huà)板的名稱(chēng)。Screen1為應(yīng)用啟動(dòng)的第一個(gè)屏幕,首先在Screen1的組件屬性中,將對(duì)齊方式設(shè)置為“上中”,屏幕方向設(shè)置為“鎖定橫屏”,去除“是否顯示狀態(tài)欄”和“是否顯示標(biāo)題欄”前面的勾選。然后從組件面板的“界面布局”中拖入一個(gè)水平布局,對(duì)齊方式設(shè)置為正中,寬度設(shè)置為充滿(mǎn),高度為50dp。再按照?qǐng)D2的原型設(shè)計(jì),添加輸入框和按鈕等其他組件,完成的設(shè)計(jì)如圖4所示。
4.2 啟動(dòng)界面的邏輯設(shè)計(jì)
進(jìn)入邏輯設(shè)計(jì)視圖前,先“增加屏幕”,命名為DrawingBoard,也就是點(diǎn)擊“開(kāi)始繪畫(huà)”按鈕后進(jìn)入的屏幕。當(dāng)“開(kāi)始繪畫(huà)”按鈕被點(diǎn)擊時(shí),如果畫(huà)板名稱(chēng)不為空,就進(jìn)入 DrawingBoard 屏幕,否則顯示提示信息。進(jìn)入邏輯設(shè)計(jì)視圖,點(diǎn)擊模塊中的“按鈕_開(kāi)始繪畫(huà)”,將“當(dāng)‘按鈕_開(kāi)始繪畫(huà)被點(diǎn)擊”圖形塊拖進(jìn)工作面板,開(kāi)始邏輯設(shè)計(jì),完成的設(shè)計(jì)如圖5所示。
4.3 繪畫(huà)界面的組件設(shè)計(jì)
首先在屏幕屬性中,將屏幕方向設(shè)置為“鎖定橫屏”,隱藏狀態(tài)欄和標(biāo)題欄。從“界面布局”中將“層疊布局”拖入工作面板,寬高設(shè)置為充滿(mǎn),再?gòu)摹袄L圖動(dòng)畫(huà)”中拖入畫(huà)布放到層疊布局中,寬高設(shè)置為充滿(mǎn)。按照?qǐng)D3的原型設(shè)計(jì)加入其他組件,完成后如圖6所示。
在工作面板的下方,有三個(gè)不可見(jiàn)組件,其中的 MQTT 客戶(hù)端用于向 MQTT Broker 發(fā)布和訂閱消息,計(jì)時(shí)器又是什么用途呢?在繪畫(huà)時(shí),隨著手指的移動(dòng)短時(shí)間產(chǎn)生大量坐標(biāo)點(diǎn)信息,如果直接將這些坐標(biāo)點(diǎn)發(fā)布出去,將會(huì)發(fā)生消息堵塞或者錯(cuò)位。因?yàn)?MQTT Broker 可能對(duì)消息的發(fā)布頻率有限制,而且由于每次發(fā)送消息的網(wǎng)絡(luò)通信時(shí)間不確定,相差若干毫秒的兩個(gè)消息,可能出現(xiàn)先發(fā)送的消息后到達(dá)服務(wù)器的情況。為此,需要先將筆畫(huà)坐標(biāo)點(diǎn)放到消息隊(duì)列中,在計(jì)時(shí)器到達(dá)設(shè)定時(shí)間間隔后再發(fā)送,降低發(fā)送消息的頻率。如果時(shí)間間隔設(shè)置過(guò)長(zhǎng),就會(huì)出現(xiàn)比較大的消息延遲,如果設(shè)置過(guò)短又會(huì)導(dǎo)致前面所述的問(wèn)題。一般設(shè)置為MQTT客戶(hù)端與MQTT Broker連接延遲的3倍以上,不低于100毫秒。
4.4 繪畫(huà)界面的邏輯設(shè)計(jì)
從啟動(dòng)界面進(jìn)入繪畫(huà)界面時(shí),將所填寫(xiě)的畫(huà)板名稱(chēng)記錄到全局變量中,并嘗試連接MQTT Broker,連接成功才啟動(dòng)計(jì)時(shí)器定時(shí)處理筆畫(huà)消息隊(duì)列,具體實(shí)現(xiàn)如圖7所示。
當(dāng)手指在畫(huà)布按下時(shí)設(shè)置筆畫(huà)列表為空,在畫(huà)布組件中移動(dòng)時(shí)將劃過(guò)的坐標(biāo)點(diǎn)加入消息隊(duì)列,具體實(shí)現(xiàn)如圖8和圖9所示。
當(dāng)計(jì)時(shí)器到設(shè)定的計(jì)時(shí)間隔點(diǎn),將筆畫(huà)信息發(fā)布到MQTT Broker,以便本機(jī)及其他訂閱了相同主題的手機(jī)收到。需要注意的是,將筆畫(huà)信息加入消息隊(duì)列后要將全局變量中記錄的筆畫(huà)信息清空,并將最后一個(gè)坐標(biāo)點(diǎn)放回筆畫(huà)記錄字典中,實(shí)現(xiàn)如圖10所示。
當(dāng)MQTT客戶(hù)端收到消息時(shí),將文本格式的JSON轉(zhuǎn)為字典結(jié)構(gòu),讀出筆畫(huà)信息并據(jù)此在畫(huà)布中繪畫(huà)。實(shí)現(xiàn)如圖11所示。
5 結(jié)束語(yǔ)
本文實(shí)現(xiàn)的“多人協(xié)作繪畫(huà)板”實(shí)例涉及變量、函數(shù)、數(shù)據(jù)結(jié)構(gòu)、網(wǎng)絡(luò)通信等多方面的知識(shí),限于篇幅不能展開(kāi)討論。實(shí)現(xiàn)部分也只能粗略介紹消息發(fā)布與訂閱相關(guān)的邏輯,沒(méi)有進(jìn)行異常處理及容錯(cuò),如連接MQTT失敗時(shí)如何繼續(xù)本地繪畫(huà)等,如何完善留待讀者思考。畫(huà)布的撤銷(xiāo)與重做機(jī)制也沒(méi)有實(shí)現(xiàn),在教學(xué)環(huán)節(jié)中這些“不足”與“缺陷”可以根據(jù)教學(xué)時(shí)長(zhǎng)擴(kuò)展,也可以作為留給學(xué)生的作業(yè),讓學(xué)生繼續(xù)探索以加深理解。
參考文獻(xiàn):
[1] Wolber D,Abelson H,Spertus E,et al.App inventor[J]. O'Reilly Media,Inc.,2011.
[2] Patton E W,Tissenbaum M,Harunani F.MIT App Inventor:Objectives,Design,and Development [C]//Computational thinking education.Singapore:Springer,2019:31-49.
[3] About Us[EB/OL].[2021-09-20].http://appinventor.mit.edu/about-us.
[4] MIT App Inventor 2[EB/OL].[2021-09-20].http://ai2.appinventor.mit.edu.
[5] MQTT:The Standard for IoT Messaging[EB/OL].[2021-09-20].https://mqtt.org.
【通聯(lián)編輯:謝媛媛】