2012年9月28日 星期五

當然一定要 Hello World:難的部分

當然一定要 Hello World:難的部分

This document is provided as is. You are welcomed to use it for non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
請勿轉貼

如果你來到這個網頁,相信你已經執行完你的第一個 Android 程式:Hello World;由於我們採用的是"知難行易"的方式來說明,相信之前的操作(行易)還蠻簡單的,可是只會操作而不知其所以然,想要繼續開發 Android 程式會非常困難,所以這份文件試著只解釋必須知道的部分 -- 知難。



首先,我們回想一下之前圖 4 中(提供如下)顯示的 "Create Activity",讓我們就從 Activity 開始說明。


[圖 4]



Android 應用程式主要由下列四種元件所組成,我們先大概說明一下其中三項,不懂沒關係,等用到相關元件時就清楚了:
  1. Services:提供服務用的,一般來說是沒有介面的;例如 HTC 的氣象服務,他會每隔一段時間就跟遠端取得最新氣象。
  2. Broadcast Receivers:用來接收廣播訊息的元件;廣播訊息的範例有地點改變(GPS/3G/Wifi)、電池快沒電了。
  3. Content Provider:提供資料給其他程式的元件。
最後一種就是 Activity,也是我們先解釋的一種元件。一個 Activity 物件代表一個使用者的介面或者畫面,依照 Java 的說法,Activity 是一個類別;在預設的情形下,Android 會提供一個視窗讓 Activity 將東西(例如標籤、按鈕等 GUI 元件)畫上去;而這個視窗在預設的 情形下,會填滿整個螢幕。以 Hello World 這個程式而言,它是一個 Activity 物件,該物件有如下圖紅色框框圍起來的部分。

[圖 11]
讓我們看一下,剛剛的程式的內容,其完整的原始碼如下:

[圖 12]
從程式碼可以看出:Hello World 程式其實是一個 Hello1Activity 類別;由於該類別繼承了 Activity (或者更完整的說:android.app.Activity),所以圖 12 紅色框框的物件就是 Hello1Activity 物件。
再看看程式碼,我們大概可以看出:執行 Hello1Activity 時會執行 onCreate() 這個方法, 可是為什麼或者什麼時候執行該方法呢?根據 Android 的規定,每個 Activity 物件都有它 一定的生命週期,其生命周期的圖如下所示:(參考 http://developer.android.com/guide/topics/fundamentals.html#lcycles)

[圖 13]
有興趣的讀者,可以仔細閱讀該圖。為了讓"知難"的困難度降低,我們只談圖中紅色框框的部分; 紅色框框特別標示出,一旦一個 Activity 物件開始執行,Android 系統就會呼叫該物件的 onCreate() 方法。
學過 Java 的人都知道,想要寫好程式必須懂得讀 API 文件,Android 相關文件包含在 Android SDK 內;以本文件的安裝方式,這些文件可以在 f:\AndroidSDK\docs\reference\packages.html 找到。在文件內,請仔細找出 android.app.Activity 的說明,並特別注意 onCreate() 的用法, 說明中特別提到:所有 Activity 的子類別都必須呼叫其父類別的同一個方法,也就是
  super.onCreate(savedInstanceState);
而 savedInstanceState 的資料型態是 Bundle,我們暫時只需要知道:Bundle 主要的功能在於儲存/傳遞資料; 本例中的名稱可以大概說明其用途(格式類似 key=value;類似 JSP/servlet 的 session) 經過測試,本例中 savedInstanceState 的值為 null。
onCreate() 的前一行出現一個 @Override 的用法,它的功能是什麼?名稱前面加上 @ 的用法, 稱之為 annotation(註解),主要的目的在於提供更多的資訊給 compiler 或者其他處理程式使用。 Java 定義了三種註解給 compiler 用,分別是 @Deprecated, @Override, 以及 @SuppressWarnings; @Override 用於確保在程式中所寫的方法(在本例中是 onCreate())是重載了(overriding)父類別的方 法,以確保不會筆誤。
最後,讓我們解釋一下下列三行敘述。一般來說,我們可以在 Activity 內放上 GUI 元件;這個概念類似 Activity 是一個盤子,而我們把需要顯示的 GUI 元件(GUI 元件必須是 android.view.View 的子類別)放在盤子上。 由於本例中的 TextView 是 android.view.View 的子類別,所以我們可以把它放到 Activity 內。
TextView tv = new TextView(this);
tv.setText("Hello World");
setContentView(tv);
由於我們希望能在 Activity 中顯示一串文字,因此選擇 TextView,產生 TextView 物件的方式如下:
TextView tv = new TextView(this);
TextView 的建構元需要一個 android.content.Context 的物件當作參數,由於 Activity 是 Context 的子類別,因此我們就使用 this (也就是 Hello1Activity 物件)。Context 的主要目的在於提供程式與 Android 系統的連繫,可以經由它來取得系統資源。
tv.setText("Hello World");
以上敘述將 tv 的內容設定成字串 "Hello World",這個字串可以是任意字串。最後,我們經由
setContentView(tv);
把 tv 的內容顯示在 Activity 中。或者有細心的讀者會注意到,這個程式碼中並沒有定義 setContentView() 的程式碼, 為什麼程式仍然可以呼叫它?其實這是 Hello1Activity 從 Activity 繼承下來的方法。
回目錄
練習題: 請查出 setContentView() 可以接受的參數類別為何?去查看 View 的其他子類別,例如 AnalogClock, 然後試著完成下列畫面:

Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu

沒有留言:

張貼留言