本章將從程序員的視角來探討應(yīng)用的結(jié)構(gòu)問題。先從一個經(jīng)典的比喻開始,將應(yīng)用理解為一份菜譜,然后再從組件的角度,理解其對事件的響應(yīng),從而對應(yīng)用產(chǎn)生新的認(rèn)識。本章還將探討應(yīng)用如何提問、重復(fù)、記憶以及與Web交互,所有這些在后面章節(jié)均有更詳細(xì)的敘述。
大多數(shù)人是從用戶的角度來描述一個應(yīng)用,但是在程序員看來,應(yīng)用要復(fù)雜得多。我們必須充分理解應(yīng)用的內(nèi)部結(jié)構(gòu),才能更加有效地創(chuàng)建應(yīng)用。
通常從兩個方面來描述應(yīng)用的內(nèi)部結(jié)構(gòu):組件及行為,這大致與App Inventor的兩個主要窗口相對應(yīng):組件設(shè)計器及塊編輯器。前者用來設(shè)定應(yīng)用中的對象(組件),而后者用來編寫程序,實現(xiàn)對用戶及外部事件的響應(yīng)(應(yīng)用程序的行為)。
在圖14-1中,對應(yīng)用的架構(gòu)給出了總體描述,本章將對這種架構(gòu)進(jìn)行深入細(xì)致的探討。
圖 14-1 App Inventor應(yīng)用的內(nèi)部結(jié)構(gòu)
應(yīng)用中的組件分為兩大類:可視組件及非可視組件??梢暯M件是在應(yīng)用啟動后能夠看到的組件,如Button、Textbox及Label等,這些通常被視為應(yīng)用的用戶界面。
非可視組件是不可見的,因此它們不是用戶界面的組成部分,通常用于訪問設(shè)備的內(nèi)置功能,如,Texting組件用于收發(fā)短信,LocationSensor組件用于確定設(shè)備的位置,而TextToSpeech組件用于朗讀文字。非可視組件是設(shè)備的技術(shù)核心,是服務(wù)于應(yīng)用程序的小精靈。
兩類組件都是由一組屬性來定義,屬性相當(dāng)于組件信息的存儲空間。如可視組件的Width、Height及Alignment屬性,它們共同定義了組件的外觀。因此,最終用戶所看到的如圖14-2所示的“Submit”按鈕,實際上是在組件設(shè)計器中由一組屬性所定義的,如表14-1所示。
表14-1 按鈕屬性
Width | Height | Alignment | Text |
---|---|---|---|
50 | 30 | center | Submit |
圖 14-2 提交按鈕
可以將屬性理解為上面表格中的內(nèi)容,在組件設(shè)計器中,用它們來定義組件的初始外觀。如果將Width屬性從50改為70,那么無論是在設(shè)計器中,還是在實際應(yīng)用中,按鈕看起來都會變寬。注意,最終用戶不會看到70這個數(shù)字,他們只能看到按鈕變寬。
一般來說,人們很容易了解組件的用途:文本框(Textbox)用于輸入信息,按鈕(Button)用來點擊等等。但是對于應(yīng)用中的行為,則往往是抽象的和復(fù)雜的。行為定義了應(yīng)用對事件的響應(yīng),無論是用戶發(fā)起的事件(如點擊按鈕),還是外部事件(如手機(jī)收到短信)。定義這些交互行為的難度恰恰是編程的挑戰(zhàn)性所在。
幸運的是,App Inventor提供了一種非常適合于定義行為的可視化“塊”語言,本節(jié)為理解塊語言提供了一種模型。
人們習(xí)慣于把軟件與菜譜相對比。像菜譜一樣,傳統(tǒng)的應(yīng)用由一系列的順序排列的指令構(gòu)成,如圖14-3所示,而計算機(jī)(廚師)則按順序執(zhí)行這些指令。
圖 14-3 傳統(tǒng)的軟件由一系列順序執(zhí)行的指令構(gòu)成
一項典型的銀行業(yè)務(wù)可能按如下順序執(zhí)行:
1. 啟動某項業(yè)務(wù);
2. 執(zhí)行某些計算并修改客戶賬目;
3. 在屏幕上顯示新的余額信息。
然而,如今的絕大多數(shù)應(yīng)用,無論是手機(jī)的,還是Web或桌面電腦的,都不再適合采用這種菜譜模式了。應(yīng)用不再是順序地執(zhí)行一系列的指令,相反,更為普遍的是對事件的響應(yīng),事件的觸發(fā)者是最終用戶。例如,當(dāng)用戶點擊按鈕時,程序會做出響應(yīng),執(zhí)行某些操作(如發(fā)送短信)。對于使用觸屏的手機(jī)或設(shè)備,當(dāng)你的手指在屏幕上拖動時,將觸發(fā)另一類事件,在應(yīng)用中可以利用這類事件,在手指最初的接觸點與最終的抬起點之間畫一條線,作為對該事件的響應(yīng)。
這種類型的應(yīng)用更適合于概括為“對事件做出響應(yīng)的組件的集合”。這類應(yīng)用中依然包含了“菜譜”——一些順序執(zhí)行的指令,但每個菜譜只限于對某些特定事件做出響應(yīng),如圖14-4所示的“菜譜”。
圖 14-4 擁有多個“事件菜譜”的應(yīng)用
因此,當(dāng)事件發(fā)生時,應(yīng)用通過調(diào)用一系列的函數(shù)進(jìn)行回應(yīng)。這里的函數(shù)是指①利用某些組件來完成某些操作,如發(fā)送短信;②對某些組件屬性進(jìn)行操作,如在用戶界面上修改label的text屬性。調(diào)用函數(shù)意味著讓函數(shù)運行,讓它產(chǎn)生作用。我們把事件,連同對事件進(jìn)行響應(yīng)的一系列函數(shù)統(tǒng)稱為事件處理程序(Event Handler)。
許多事件由最終用戶觸發(fā),但還有些不是。應(yīng)用可以對手機(jī)內(nèi)部的事件進(jìn)行響應(yīng),如方向傳感器的變化以及時鐘的行走(即時間的流逝),也可以對手機(jī)以外的事件做出響應(yīng),如來自于其他手機(jī)的事件,或收到來自web的數(shù)據(jù),等等。如圖14-5所示。
圖 14-5 應(yīng)用可以兼顧對內(nèi)部及外部事件的響應(yīng)
之所以稱App Inventor編程為“直觀”編程,是因為這種編程完全基于一種事件響應(yīng)模式,而“事件處理程序”則是該語言中最重要的詞匯(在其他語言中情況未必如此)。想要定義某個行為,首先要拖出一個事件塊,事件塊在形式上是這樣的:“When do”。假設(shè)有這樣一個“朗讀”應(yīng)用,當(dāng)用戶點擊按鈕時,應(yīng)用大聲讀出用戶輸入的文字,這個應(yīng)用只需要一個事件處理程序,如圖14-6所示。
圖 14-6 “朗讀”應(yīng)用中的事件處理程序
這些塊的作用是,當(dāng)用戶點擊“SpeakItButton”按鈕時,TextToSpeech組件將朗讀用戶在輸入框TextBox1中輸入的文字。在這里,事件是SpeakItButton.Click,對事件的響應(yīng)是調(diào)用TextToSpeech1.Speak函數(shù),事件處理程序中包括了圖14-6中的所有塊。
在App Inventor中,所有活動都發(fā)生在對事件的響應(yīng)之中,應(yīng)用中不可能存在事件塊“when-do”之外的塊,如圖14-7這樣的單擺浮擱的塊是毫無意義的。
圖 14-7 事件處理程序之外的散在的塊毫無用處
可以引發(fā)活動的事件被分類列在表14-2中。
表14-2 能夠引發(fā)活動的事件
事件類型 | 舉例 |
---|---|
用戶發(fā)起的事件 | 當(dāng)用戶點擊Button1時,執(zhí)行... |
初始化事件 | 當(dāng)應(yīng)用啟動時,執(zhí)行... |
計時器事件 | 當(dāng)20毫秒過去時,執(zhí)行... |
動畫事件 | 當(dāng)兩個物體碰撞時,執(zhí)行... |
外部事件 | 當(dāng)電話收到短信時,執(zhí)行... |
用戶引發(fā)的事件是一種最常見的事件類型,在輸入表單中,通常點擊按鈕事件會引發(fā)應(yīng)用的響應(yīng)。圖形化的應(yīng)用更多的是對觸摸及拖拽事件做出響應(yīng)。
有時需要在應(yīng)用啟動時實現(xiàn)某些功能,這既不同于響應(yīng)最終用戶引發(fā)的事件,也不是對其他類型事件的響應(yīng),那么如何讓這種情況也適合于事件處理模式呢?
在App Inventor這種基于事件處理的語言中,應(yīng)用的啟動也被視為一種事件。如果你想在應(yīng)用打開的同時實現(xiàn)某些功能,可以拖出Screen1.Initialize事件塊,并將某些函數(shù)調(diào)用塊放在其中。
例如,在第三章打地鼠游戲中,在應(yīng)用啟動的同時,通過調(diào)用MoveMole過程,將地鼠放在一個隨機(jī)的位置,如圖14-8所示。
圖 14-9 一旦Clock1.Timer開始運行(計時),使用計時器事件塊來移動球
在canvas范圍內(nèi)的圖形對象(sprites精靈),它們的活動將觸發(fā)動畫事件,具體地說,當(dāng)兩個sprites發(fā)生碰撞,或一個sprites到達(dá)canvas的邊界時,將觸發(fā)動畫事件。因此可以編寫游戲或其他交互式動畫程序,利用動畫事件來定義游戲或動畫的情節(jié)。更多信息請參見第17章。
當(dāng)手機(jī)從接收到來自GPS衛(wèi)星的位置信息時,將觸發(fā)一個外部事件;同樣,當(dāng)手機(jī)收到短信時,也會觸發(fā)此類事件(圖14-10)。
更多建議: