<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                Facebook的數據庫中,有每位用戶的賬戶信息、好友列表以及發布的信息,Amazon的數據庫中有你能買到的任何東西,而Google的數據庫中有互聯網上的每個頁面的信息。你自己的應用雖然沒有那么大的規模,但一個正規的應用都會用到數據庫組件。 在大多數的編程環境中,編寫與數據庫通信的應用是一種高級編程技術:要搭建數據庫(軟件)服務器,如Oracle或MySQL等,并編寫程序與數據庫建立連接。在大學里,這些內容通常要在軟件工程或數據庫這樣的高級課程中才會涉及。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403a0da79b.png) App Inventor承擔了與數據庫(以及許多其它有用的事情)有關的這部分繁瑣的設置,在這個語言中,提供了數據庫組件,將數據庫通信簡化為單純的讀寫操作。應用可以直接將數據保存在Android設備上,也可以保存到集中式網絡數據庫中,從而實現在不同設備與其他人之間的數據共享。 保存在變量及組件屬性中的數據屬于臨時存儲:如果用戶在表單中輸入某些信息然后關閉應用,那么當應用重新打開時,這些信息將不復存在。想要長期保存信息,就需要將它們保存到數據庫中。數據庫中的信息被稱為永久信息,因為當應用在關閉后重新打開時,數據依然存在。 作為例子,考慮第4章開車不發短信的應用,那個繁忙時自動回復短信的應用。這個應用允許用戶輸入一條個性化的信息,作為收到短信時的自動回復信息。如果用戶將信息改為“我在睡覺,別來煩我”,然后關閉了應用,當重新打開應用時,定制的自動回復信息依然是“我在睡覺,別來煩我”。因此,定制信息必須保存到數據庫中,在每次啟動應用時,再將信息從數據庫提取到應用中。 ## **在TinyDB中永久保存數據** App Inventor提供了兩個便于操作數據庫的組件:TinyDB及TinyWebDB。TinyDB用于直接在Android設備上永久保存數據,它適合于那些極其私人化的應用,如開車不發短信,這類應用不需要讓數據在不同設備及人群之間共享。而TinyWebDB則將數據保存到web數據庫中,并可實現不同設備之間的共享。能夠通過web數據庫訪問數據,這是多人游戲及應用的基礎,用戶可以借此分享信息(如第10章的出題應用)。 這兩個數據庫組件非常相似,但TinyDB更簡單些,因此我們先來研究它。首先,不需要任何設置就可以直接使用它,此外,數據直接保存在設備上,并于應用相關聯。 使用TinyDB.StroeValue塊來實現數據的長期存儲,如圖22-1所示,這段代碼來自于“開車不發短信”。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403a20786c.png) **圖 22-1 TinyDB.StoreValue塊將數據永久保存到設備中** 數據庫存儲中用到了tag-value(標簽-值)模式,在圖22-1中,數據的標簽是“responseMessage”,而值是用戶輸入的內的自動回復信息,比如“我在睡覺,別來煩我”。 標簽是數據的名稱,是信息查詢的依據,而致才是數據本身。可以將標簽理解為鑰匙,必須用它從數據庫中提取已經存儲的數據。 同樣,可以將App Inventor的TinyDB數據庫理解為一個表,其中包含了許多tag-value對兒,在圖22-1中的TinyDB.StoreValue塊執行完成后,設備數據庫將增加一條輸入,如表22-1中所列。 **表22-1 存儲到數據庫中的tag-value對:“responseMessage”-“我在睡覺,別來煩我”** | tag | value | | --- | --- | | responseMessage | 我在睡覺,別來煩我 | 一個應用中可以有許多tag-value對,用來永久保存需要保留的各種數據項。標簽必須是文本,而值既可以是單個的數據(一段文本或一個數字),也可以是一個列表。每個標簽只能對應一個值,當你使用同一個標簽保存一個新值時,將覆蓋原來的值。 ### **從TinyDB中提取數據** 從數據庫中提取數據要用到TinyDB.GetValue塊。在調用GetValue塊時,通過提供標簽(tag)來請求特定的數據。在“開車不發短信”中,使用在保存數據時(StoreValue)用過的標簽“responseMessage”來請求定制的回復信息。調用GetValue所獲得的返回數據,必須插入到一個變量中。 通常要在應用打開時從數據庫中提取數據。App Inventor提供了一個特別的事件處理程序Screen.Initialize,應用啟動時會觸發該程序。需要格外小心地處理數據庫為空的情況(如,應用第一次啟動時),因此當使用GetValue時,要指定一個“valueIfTagNotThere”參數,一旦數據庫為空,則GetValue將返回該參數值。 圖22-2中的塊顯示了在“開車不發短信”中,如何在應用初始化時,使用Screen.Initialize加載數據。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403a775579.png) **圖 22-2 應用啟動時加載數據的一種模式** 這里將GetValue的返回值寫入到ResponseLabel組件中。如果數據庫中已經存儲過數據,則將讀取的數據寫入ResponseLabel中,如果沒有與標簽responseMessage相對應的數據,則將“我正在開車...”寫入Label。 ## **用TinyWebDB保存并共享數據** TinyDB組件將數據保存在Android設備的本地數據庫中,這一點適用于那些不需要數據共享的個人應用,例如很多人都可以下載“開車不發短信”應用,但每個人都使用個性化的自動回復信息,這類信息不需要與其他人共享。 當然,更多的應用需要數據共享:像Facebook、Twitter以及像Words With Friends這樣流行的多人游戲,這些應用的數據庫必須運行在網絡上,而非設備上。另一個例子是第10章的“出題/答題”應用,某人在手機上生成了一份測試,并將其保存到網絡數據庫中,這樣其他人就可以在其他手機上加載測驗,并回答問題。 TinyWebDB是TinyDB的web版本,可以讓應用將數據保存到web上,方法與TinyDB類似,使用StoreValue與GetValue協議。 默認情況下,TinyWebDB組件使用由App Inventor團隊創建的web數據庫保存數據,從[http://appinvtinywebdb.appspot.com](http://appinvtinywebdb.appspot.com/)可以訪問到該數據庫。該網站包括一個數據庫,并能響應來自web的保存及提取數據的請求;此外,還提供了一個人類可讀的web接口,可以讓數據庫管理員(也就是你)能夠查看到在此保存的數據。 感興趣的話,可以在瀏覽器中訪問[http://appinvtinywebdb.appspot.com](http://appinvtinywebdb.appspot.com/),并檢查保存在此的tag-value類型的數據。 這個默認的數據庫僅用于開發,對于所有App Inventor程序員提供了有限的空間和權限。由于所有的App Inventor應用都可以使用該數據庫,因此不能確保你的數據不被其它的應用所覆蓋。 如果你只是在研究學習App Inventor,或者在項目的早期階段,默認的web數據庫就足夠了,但如果你想創建正式發布的應用,從某種意義上講,你需要建立自己的web數據庫。由于我們正在學習,因此可以使用默認的數據庫。在本章的后面將學習如何創建自己的web數據庫,并配置TinyWebDB,來替代默認的數據庫。 在這一節中,我們通過一個投票應用(如圖22-3所示)來描述TinyWebDB的用法。該應用具有如下特性: ![{%}](https://box.kancloud.cn/2015-08-31_55e403a7dd1b8.png) **圖 22-3 投票應用:將投票結果保存到TinyWebDB中** * 每次應用打開之后,提示用戶輸入自己的email地址,該地址既是用戶名,又是保存到數據庫中的投票信息的標簽(tag); * 任何時候用戶都可以提交新的投票內容,這種情況下,原有的投票內容將被覆蓋; * 用戶可以看到群組中每個人的投票結果; * 為簡單起見,需要投票的議題在應用之外發布,如課堂上,教師宣布議題并要求每個學生進行電子投票。(注意,這個例子的功能可以擴展,在應用中允許用戶輸入并提示投票議題。) ### **用TinyWebDB保存數據** TinyWebDB.StoreValue的作用與TinyDB.StoreValue一樣,只不過是將數據保存到Web上。在這個投票的例子中,假設用戶會在文本框VoteTextBox中輸入投票內容并點擊按鈕VoteButton發送投票結果。將投票結果保存到web數據庫中,以便其他人也能看到它,我們將編寫如圖22-4所示的事件處理程序VoteButton.Click。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403a860909.png) **圖 22-4 用VoteButton.Click事件處理程序將投票結果保存到數據庫中** 用于識別數據的標簽是用戶的email地址,之前已經被保存到變量myEmail中(稍后將看到),而要保存的值是用戶在VoteTextBox輸入的內容。因此,如果用戶的email地址是“wolber@gmail.com”,而他的投票是“Obama”,則作為整體存入數據庫的信息如表22-2所示。 **表22-2 記錄在數據庫中的標簽(tag)及值(value)** | tag | value | | --- | --- | | wolber@gmail.com | Obama | TinyWebDB.StoreValue塊將這個tag-value對發送到位于[http://appinvtinywebdb.appspot.com](http://appinvtinywebdb.appspot.com/)的web數據庫服務器中。由于這里用的是默認的服務,會顯示來自于各種應用的很多數據,因此在第一個顯示窗口中,有可能看到,也有可能看不到你的數據。如果看不到,可以用頁面上的GetValue鏈接用特定標簽來搜索數據。 > ![](https://box.kancloud.cn/2015-08-31_55e403a8efe7a.png) 測試:用TinyWebDB編程時,使用數據庫服務器的web接口來測試是否按要求被保存起來。 ### **用TinyWebDB來請求并處理數據** 用TinyWebDB提取數據要比TinyDB復雜得多。由于TinyDB的GetValue操作是直接與Android設備上的數據庫通信,因而可以立即獲得返回值,但使用TinyWebDB的應用則需要跨越網絡來請求數據,因此需要分兩步來實現。 首先使用TinyWebDB的GetValue請求數據,稍后再來處理TinyWebDB.GotValue事件處理程序。實際上,TinyWebDB.GetValue應該叫做“RequestValue(請求值)”,因為他只是向web數據庫發出請求,而請求實際上并不能立即“get(得到)”一個值。為了更清楚地了解二者之間的差別,可以對比圖22-5中的TinyDB.GetValue與圖22-6中的TinyWebDB.GetValue。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403ae60839.png) **圖 22-5 TinyDB.GetValue塊** ![{%}](https://box.kancloud.cn/2015-08-31_55e403aecdacb.png) **圖 22-6 TinyWebDB.GetValue塊** TinyDB.GetValue塊立即得到返回值,因此該塊的左側有一個插頭以便可以將返回值保存到一個變量或屬性中;而TinyWebDB.GetValue塊不能立即得到返回值,因此左側沒有插頭。 對TinyWebDB而言,當web數據庫實現了請求并將數據返回給設備時,將觸發TinyWebDB.GotValue事件。因此整個提取數據過程分為兩步,首先在一個地方調用TinyWebDB.GetValue,然后再編寫TinyWebDB.GotValue事件處理程序,來處理實際接收到的數據。像TinyWebDB.GotValue這樣的程序有時被稱作回調過程,因為實際上是某些外部實體(這里是web數據庫)在處理完你的請求之后,反過來調用你的程序。就像在一家繁忙的咖啡店點餐一樣:你點餐,然后等待咖啡師喊你的名字,你才能真正拿到你的飲料。在同一時間,咖啡師會按順序從每個人手里收取點餐單(而且所有人都在等待自己的名字被喊到)。 ### **GetValue-GotValue連動** 在我們的例子中,需要保存并提取一個投票者的列表,并最終顯示所有人的投票結果。 最簡單的方案是在應用啟動時,在Screen.Initialize事件中發出請求來提取列表數據。如圖22-7所示(在本例中,用“voterlist”為標簽向數據庫發出請求。) ![{%}](https://box.kancloud.cn/2015-08-31_55e403af37bba.png) **圖 22-7 在Screen.Initialize事件中請求數據** 當應用從數據庫收到投票者列表的數據時,TinyWebDB.GotValue事件被觸發,圖22-8顯示了處理這個返回列表的塊。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403b48bd60.png) **圖 22-8 使用TinyWebDB.GotValue事件處理程序處理返回的列表** 程序GotValue附帶了參數valueFromWebDB,其中保存著向數據庫請求的數據。像valueFromWebDB這樣的事件附帶的參數,只在該事件處理程序范圍內有效(隸屬于該事件處理程序),因此無法在其他事件處理程序中引用該參數。 這一點看似有些費解,但一旦你熟悉了這些保存局部數據的參數,你自然會聯想到那些適用范圍更大的數據(在整個應用中隨處可用):變量。理解了這一點,也就理解了GotValue中的關鍵一步:將返回的數據valueFromWebDB轉移到一個變量中。這里是將數據轉移到變量voterList中,之后可以在其他的事件處理程序中使用該變量。 通常會在GotValue中同時使用if塊,原因是,如果數據庫中不存在被請求的數據,則返回值為空文本(“”),通常這種情況發生在第一次啟動應用時。通過檢查valueFromWebDB是否為列表,可以確定是否真的有數據返回。如果valueFromWebDB為空(if的測試結果為假),就不必將其寫入變量voterList。 無論是TinyDB還是TinyWebDB,都是以相同的方式來獲取數據、檢查數據及設置數據(到變量中),不同的是,這里預期會收到一個列表,因此測試環節上略有差別。 ### **更為復雜的GetValue/GotValue舉例** 在相對簡單的應用中,圖22-8中所示的代碼是一種不錯的提取數據的方式,但在投票的例子中,我們需要更為復雜的邏輯。說明如下: * 應用啟動時,程序會提示用戶輸入Email地址。可以使用Notifier組件彈出窗口來實現這一功能。(Notifier在組件設計器組件面板的User Interface中。)用戶輸入email后,將其保存為變量; * 檢查完用戶的email之后,調用GetValue來提取投票人列表。你能說出為什么嗎? 圖22-9顯示了向數據庫請求數據的更為復雜的方案。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403beede72.png) **圖 22-9 在這個更為復雜的方案里,在獲得用戶的email之后調用GetValue** 在應用啟動時(Screen1.Initialize),Notifier組件提示用戶輸入他的email地址;用戶輸入后(Notifier.AfterTextInput),輸入的信息保存到變量中,同時用label顯示出來,然后調用GetValue來獲得投票人列表。需要注意,這里沒有在Screen1.Initialize中直接調用GetValue,因為需要首先設置用戶的Email地址。 因此當應用初始化完成后,用這些塊來提示用戶的Email地址,然后以“voterlist”為標簽調用GetValue。當從web上返回列表時,GotValue被觸發,以下是后續功能的描述: * GotValue將檢查到達的數據是否不為空(有人已經使用這個應用,并建立了投票人列表)。如果返回值中包含數據(投票人列表),則檢查此用戶的email是否已經在投票人列表中,如果沒有,將其添加至列表,并將更新后的列表保存到數據庫; * 如果數據庫中沒有投票人列表,我們將以此用戶的email作為唯一的項來創建列表。 圖22-10中顯示了這一功能所需的塊。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403c96d9a3.png) **圖 22-10 使用GotValue塊處理數據庫返回的數據,根據不同的返回結果確定要執行的操作** 在這些塊中,第一個if通過調用“is a list?”來檢測從數據庫返回的值,判斷其是否不為空。如果不為空,返回的數據放入變量voterList中。切記,voterList中只有每個使用過該應用的用戶的Email地址,但我們不確定當前用戶是否也在此列表中,因此需要檢查一下:如果此用戶不在列表中,則用“add item to list”塊將其添加至列表,并將更新后的列表保存到web數據庫。 如果數據庫返回的結果不是列表,則執行ifelse塊中的“else”分支;這說明還沒有人使用過這個應用。此時需要創建一個新的列表voterList,將當前用戶的Email地址作為列表的第一項,然后將這個只有一項的列表保存到web數據庫中(同時也希望更多人的加入!)。 ### **用不同的標簽請求數據** 到目前為止,投票應用值處理了一個用戶列表,每個用戶都可以看到其他用戶的Email地址,但還不能提取并顯示每個用戶的投票結果。 此前設定在VoteButton的Click事件中,將用戶的Email地址與投票結果以“email地址:投票結果”的方式組成tag-value對提交給web數據庫。此時如果已經有兩個人投票,那么相應的數據庫實體中將包含表22-3中的數據。 **表22-3 存儲在數據庫中的tag-value對** | tag | value | | --- | --- | | voterlist | [wolver@gmail.com,joe@gmail.com] | | wolber@gmail.com | Obama | | joe@gmail.com | McCain | 當用戶點擊“ViewVotes”按鈕時,應用將從數據庫中提取所有投票結果并加以顯示。現在假設投票人列表已經提取并保存到變量voterList中,我們可以使用foreach來請求列表中每個人的投票結果,如圖22-11所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403ca11457.png) **圖 22-11 使用foreach塊請求列表中每位成員的投票結果** 這里對變量currentVotesList進行初始化,來清空列表,目的是為了將最新從數據庫中獲得的投票結果添加到列表中。在foreach中使用TinyWebDB.GetValue來處理列表中的每一個Email地址:以Email地址(voterEmail)為標簽向數據庫發送請求。需要注意的是,要等到一系列的請求數據返回時觸發GotValue事件,才能將投票結果添加到currentVotesList中。 ### **在TinyWebDB.GotValue中處理多標簽** 我們希望在應用中顯示投票結果,事情變得更加復雜了。在點擊ViewVotesButton按鈕發出請求之后,在TinyWebDB.GotValue中將收到以每個Email地址為標簽(tag)的數據,就像“voterlist”標簽用于提取用戶Email地址列表一樣。當應用同時向數據庫為不同標簽請求多余一項的數據時,就需要在TinyWebDB.GotValue中編寫代碼來處理所有可能的請求。(你可能想到編寫多個GotValue事件處理程序,來分別處理每個請求——知道為什么這樣做行不通嗎?) 為了處理這種復雜的情況,GotValue事件處理程序可以利用自帶的參數tagFromWebDB,它會告訴你當前的返回值來自于哪一個請求。因此,如果標簽是“voterlist”,我們可以像之前那樣進行處理;如果不是“voterlist”,我們可以假設它是用戶列表中某人的Email地址,來源于ViewVotesButton.Click事件處理程序中發出的請求。當這些請求返回時,我們希望將返回的數據——投票人及投票結果——添加到列表currentVotesList中,以便于向用戶顯示。 圖22-12中顯示了整個TinyWebDB1.GotValue事件處理程序。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403caa2061.png) **圖 22-12 TinyWebDB1.GotValue事件處理程序** ## **設置Web數據庫** 本章前面提到過,設立于[http://appinvtinywebdb.appspot.com](http://appinvtinywebdb.appspot.com/)的默認web數據庫僅供原型設計以及應用的測試,在向真正的用戶發布應用之前,需要為應用創建一個專用的數據庫。 訪問網站[http://appinventorapi.com/program-an-api-python/](http://appinventorapi.com/program-an-api-python/),按照上面的說明就可以創建web數據庫。該網站由本書的作者之一Wolber教授創建,網站提供了示例程序以及設置App Inventor web數據庫及API(應用程序接口)的說明。按照說明,你可以下載相關的程序,并且只要對配置文件進行少量修改,就可以使用這些程序。經過設置的代碼與之前使用的App Inventor默認數據庫相同,它運行在Google的應用引擎上——一個云計算服務,運行在Google服務器上免費的web數據庫。這樣,你就建起了屬于自己的web數據庫(與App Inventor的協議兼容),幾分鐘就可以運行起來,并用它來創建web移動應用。 一旦創建并部署了屬于自己的web數據庫(因為只有你知道它的URL地址),你就可以用它來創建應用。不過還需要在應用中修改TinyWebDB組件的ServiceURL屬性,以便組件可以用新的定制數據庫來保存及提取數據。圖22-13描述了如何操作。 ![{%}](https://box.kancloud.cn/2015-08-31_55e403d146f65.png) **圖 22-13 將ServiceURL屬性修改為你的定制數據庫的URL地址** 在這個例子中,ServiceURL被設置為[http://usfwebservice.appspot.com](http://usfwebservice.appspot.com/),是本書的作者之一為他的學生們創建的一個web數據庫(圖22-13中"appsport.com"后面的部分被輸入框遮擋住了)。設定了ServiceURL之后,所有的TinyWebDB.StoreValue及TinyWebDB.GetValue的調用都將執行這個特定的URL。 ## **小結** 通過TinyDB及TinyWebDB組件,App Inventor可以很容易地實現數據的永久存儲。數據以標簽-值(tag-value)對的方式存儲,保存數據時使用的標簽也用于之后對數據的提取。TinyDB用于將數據直接保存在設備上;當數據需要在手機之間分享時(如多人游戲或投票應用),就需要使用TinyWebDB。TinyWebDB更為復雜,尤其在獲取數據的環節,除了用GetValue來請求數據,還要設置回調過程,即GotValue事件處理程序,同時還要設置web數據庫服務。 一旦你可以得心應手地使用數據庫——尤其是掌握了獲取、檢查及設置數據的要點,要不了多久,你就能創建更為復雜的應用了。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看