分类:
2008-12-07 11:56:51
接著要觀察主要程式邏輯的內容囉。接着要观察主要程式逻辑的内容啰。 打開「src/com/demo/android/bmi」 目錄下的「Bmi.java」檔案,Eclipse+Android 開發工具已經幫我們預先建立好了基本的程式邏輯。打开「src/com/demo/android/bmi」目录下的「Bmi.java」档案,Eclipse+Android开发工具已经帮我们预先建立好了基本的程式逻辑。 其預設的內容如下:其预设的内容如下:
1 package com.demo.android.bmi; 1 package com.demo.android.bmi;
2
3 import android.app.Activity; 3 import android.app.Activity;
4 import android.os.Bundle; 4 import android.os.Bundle;
5
6 public class Bmi extends Activity { 6 public class Bmi extends Activity {
7 /** Called when the activity is first created. */ 7 /** Called when the activity is first created. */
8 @Override 8 @Override
9 public void onCreate(Bundle savedInstanceState) { 9 public void onCreate(Bundle savedInstanceState) {
10 super.onCreate(savedInstanceState); 10 super.onCreate(savedInstanceState);
11 setContentView(R.layout.main); 11 setContentView(R.layout.main);
12 } 12 }
13 } 13 }
比起什麼標籤都對稱的XML 介面描述檔來說,這個以Java 程式語言寫成的檔案雖然篇幅短,但反而要難讀得多。比起什么标签都对称的XML介面描述档来说,这个以Java程式语言写成的档案虽然篇幅短,但反而要难读得多。
我們將程式直接拆開,分成幾個部份來講解這個「Bmi.java」 檔案的內容:我们将程式直接拆开,分成几个部份来讲解这个「Bmi.java」档案的内容:
第1 行:第1行:
package com.demo.android.bmi; package com.demo.android.bmi;
這一行的作用是指出這個檔案所在的名稱空間。这一行的作用是指出这个档案所在的名称空间。「package」(套件)是其關鍵字。 「package」(套件)是其关键字。 使用名稱空間的原因是程式一旦擴展到擴展到某個大小,程式中的變數名稱、方法名稱、類別名稱難免重複, 這時就可以將定義的名稱區隔管理在package 下,以避免相互衝突的情形發生。使用名称空间的原因是程式一旦扩展到扩展到某个大小,程式中的变数名称、方法名称、类别名称难免重复,这时就可以将定义的名称区隔管理在package下,以避免相互冲突的情形发生。 Java 的package 設計成與檔案系統結構相對應,如我們的package 設定是「package com.demo.android.bmi」,則這個類別就該在指定目錄的「com/demo/android/bmi」路徑下可以找到。 Java的package设计成与档案系统结构相对应,如我们的package设定是「package com.demo.android.bmi」,则这个类别就该在指定目录的「com/demo/android/bmi」路径下可以找到。
同時也別忘了Java 程式語言每段敘述語句的結尾處,與大部分的程式語言一樣需加上一個分號「;」,以表示一行程式敘述的結束。同时也别忘了Java程式语言每段叙述语句的结尾处,与大部分的程式语言一样需加上一个分号「;」,以表示一行程式叙述的结束。
第3,4 行:第3,4行:
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
程式中預設導入了「android.app.Activity」跟「android.os.Bundle」兩個Package,在所有的Android 應用程式中都會用到這兩個Package。程式中预设导入了「android.app.Activity」跟「android.os.Bundle」两个Package,在所有的Android应用程式中都会用到这两个Package。 「import」(導入)是用作導入Package 的關鍵字。 「import」(导入)是用作导入Package的关键字。 在Java 語言中,使用到任何API 前都要事先導入相對應的Package。在Java语言中,使用到任何API前都要事先导入相对应的Package。我們馬上將學到這兩個Package 的用途。我们马上将学到这两个Package的用途。
Android 支援的Package 與標準的Java(j2se) 不盡相同。 Android支援的Package与标准的Java(j2se)不尽相同。 在寫Android 應用程式時,你偶而可能需要參考可用的API 列表,以確認使用到的Package 是否有內建支援。在写Android应用程式时,你偶而可能需要参考可用的API列表,以确认使用到的Package是否有内建支援。 後續章節中也將講解如何透過新增「jar」檔來呼叫額外的Package。后续章节中也将讲解如何透过新增「jar」档来呼叫额外的Package。
完整的API 可查閱官方的package 列表: 完整的API可查阅官方的package列表:
第6,13 行:第6,13行:
public class Bmi extends Activity { public class Bmi extends Activity {
}
第6行開始了程式的主體。第6行开始了程式的主体。 其組成是這樣的:其组成是这样的:
public class Bmi public class Bmi
「Bmi」是這個類別的名稱。 「Bmi」是这个类别的名称。 「class」則是用作宣告類別關鍵字。 「class」则是用作宣告类别关键字。 「public」關鍵字是用來修飾「Bmi」這個類別。 「public」关键字是用来修饰「Bmi」这个类别。 表示「Bmi」是個「公開」的類別,可以從package 外部取用。表示「Bmi」是个「公开」的类别,可以从package外部取用。
「public class Bmi」後面再加上「extends Activity」敘述,則表示「Bmi」 這個類別的功能、型別等全繼承自「Activity」類別。 「public class Bmi」后面再加上「extends Activity」叙述,则表示「Bmi」这个类别的功能、型别等全继承自「Activity」类别。「extends」是繼承(Inherit)類別的關鍵字。 「extends」是继承(Inherit)类别的关键字。 「Activity」是來自於我們在第3行剛導入的Package。 「Activity」是来自于我们在第3行刚导入的Package。
因此整句話的含意即:「宣告一個公開的Bmi 類別。這個Bmi 類別繼承了程式開頭導入的Activity 類別」。因此整句话的含意即:「宣告一个公开的Bmi类别。这个Bmi类别继承了程式开头导入的Activity类别」。
「{}」大括號規範了一個程式區塊。 「{}」大括号规范了一个程式区块。 大括號中的程式表達的這個程式區塊的主要內容。大括号中的程式表达的这个程式区块的主要内容。
第7 行:第7行:
/** Called when the activity is first created. */ /** Called when the activity is first created. */
第7 行提供了位於其下的函式的註釋。第7行提供了位于其下的函式的注释。 「/ /」 是Java 語言的多行註解符號,位於其中的文字內容不會被編譯。 /」是Java语言的多行注解符号,位于其中的文字内容不会被编译。 「/ 」敘述後多出來的一個「 」號被視為內文。 「/ 」叙述后多出来的一个「 」号被视为内文。 順便提醒一下,Java 程式語言中兩個斜線「//」表示的是單行註解符號。顺便提醒一下,Java程式语言中两个斜线「//」表示的是单行注解符号。 單行註解符號「//」與多行註解符號「/单行注解符号「//」与多行注解符号「/ /」不同的地方是,只有與「//」符號同行的文字才不會被編譯。 /」不同的地方是,只有与「//」符号同行的文字才不会被编译。
第8-9, 12 行:第8-9, 12行:
@Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
}
第9行開始了這個方法(Method)的主體。第9行开始了这个方法(Method)的主体。 其組成是這樣的:其组成是这样的:
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
}
「onCreate」是這個方法的名稱。 「onCreate」是这个方法的名称。 「void」則是宣告了這個方法的回傳值的型別(type)。 「void」则是宣告了这个方法的回传值的型别(type)。「public」關鍵字是用來修飾「onCreate」這個方法。 「public」关键字是用来修饰「onCreate」这个方法。 表示「onCreate」是個「公開」的方法,可以由bmi 類別外部取用。表示「onCreate」是个「公开」的方法,可以由bmi类别外部取用。
方法的回傳值的型別,即是這個方法的型別。方法的回传值的型别,即是这个方法的型别。「onCreate」這個方法使用「void」型別,表示「onCreate」這個方法不需回傳值。 「onCreate」这个方法使用「void」型别,表示「onCreate」这个方法不需回传值。
同時,這個方法傳入了一個名為「savedInstanceState」的「Bundle」型別參數,「Bundle」型別正是來自我們前面所導入的Package 之一。同时,这个方法传入了一个名为「savedInstanceState」的「Bundle」型别参数,「Bundle」型别正是来自我们前面所导入的Package之一。 我們並不需要知道太多「Bundle」型別或「savedInstanceState」實體的細節,只要知道「Bundle」的內容與手機平台的記憶體管理有關。我们并不需要知道太多「Bundle」型别或「savedInstanceState」实体的细节,只要知道「Bundle」的内容与手机平台的记忆体管理有关。
當Android 應用程式啟動、換到背景等待、關閉時,都會用到「savedInstanceState」 這個實體來處理記憶體相關的事宜。当Android应用程式启动、换到背景等待、关闭时,都会用到「savedInstanceState」这个实体来处理记忆体相关的事宜。 當然,你也可以用其他名稱來代替它。当然,你也可以用其他名称来代替它。 還好「onCreate」這個方法永遠都是傳入「Bundle savedInstanceState」這個參數,寫應用程式時只要正確照規定傳入即可,你可以不用太去在意它。还好「onCreate」这个方法永远都是传入「Bundle savedInstanceState」这个参数,写应用程式时只要正确照规定传入即可,你可以不用太去在意它。
給對Bundle 是什麼有興趣的讀者:给对Bundle是什么有兴趣的读者:
「Bundle」可以保存程式上一次關閉(凍結)時的狀態。 「Bundle」可以保存程式上一次关闭(冻结)时的状态。 你可以透過覆寫onFreeze 方法(與onCreate 方法的作用類似) 來保存凍結前的狀態。你可以透过覆写onFreeze方法(与onCreate方法的作用类似)来保存冻结前的状态。 當程式啟動(Activity 重新初始化)時,會再次呼叫onCreate 方法,你就能從savedInstanceState 中得到前一次凍結的狀態。当程式启动(Activity重新初始化)时,会再次呼叫onCreate方法,你就能从savedInstanceState中得到前一次冻结的状态。 我們也可以透過「Bundle」來將這個Activity 的內容傳到下一個Activity 中。我们也可以透过「Bundle」来将这个Activity的内容传到下一个Activity中。 之後講Activity 時,也會講解onCreate/onFreeze 等方法的關係。之后讲Activity时,也会讲解onCreate/onFreeze等方法的关系。
「{}」大括號規範了一個程式區塊。 「{}」大括号规范了一个程式区块。 大括號中的程式表達onCreate 這個程式區塊的主要內容。大括号中的程式表达onCreate这个程式区块的主要内容。
@Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState)
從前面的講解中,我們學到了在任何一個Android 專案目錄裡,只要打開「Referenced Libraries」 目錄的「android.app」 分類,都可以找到「Activity.class」這個類別。从前面的讲解中,我们学到了在任何一个Android专案目录里,只要打开「Referenced Libraries」目录的「android.app」分类,都可以找到「Activity.class」这个类别。 現在我們再深入一些查看「Activity.class」 類別。现在我们再深入一些查看「Activity.class」类别。 你 要做的,只是依照圖示,找到Android 工具中的「Referenced Libraries」 目錄,從「android.app」 分類裡找到「Activity.class」類別,並按下「Activity.class」 類別左側的三角形圖示,如此即可展開這個類別的屬性/方法列表。你要做的,只是依照图示,找到Android工具中的 「Referenced Libraries」目录,从「android.app」分类里找到「Activity.class」类别,并按下「Activity.class」类别 左侧的三角形图示,如此即可展开这个类别的属性/方法列表。
我們在Activity類別的屬性/方法列表中,發現了現在正要講解的onCreate 方法(Method)。我们在Activity类别的属性/方法列表中,发现了现在正要讲解的onCreate方法(Method)。
因為「bmi」 類別繼承自Activity 類別,所以預設「bmi」 類別中其實已經有「onCreate」方法了。因为「bmi」类别继承自Activity类别,所以预设「bmi」类别中其实已经有「onCreate」方法了。
事實上,「onCreate」 方法正是每個Activity 類別初始化時都會去呼叫的方法。事实上,「onCreate」方法正是每个Activity类别初始化时都会去呼叫的方法。 「@」開頭的語句表示裝飾子(decorator)語句,「@Override」語句的作用是告訴程式我們要覆寫這個「onCreate」方法。 「@」开头的语句表示装饰子(decorator)语句,「@Override」语句的作用是告诉程式我们要覆写这个「onCreate」方法。 當我們打開程式時,程式不再使用從「bmi」 類別中繼承來的「onCreate」方法,而是使用我們在程式中自訂的行為。当我们打开程式时,程式不再使用从「bmi」类别中继承来的「onCreate」方法,而是使用我们在程式中自订的行为。
@Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
}
我們講解了整段程式,其含意是「覆寫bmi 類別中公開的onCreate 方法。這個「onCreate」 方法無回傳值型別,而且這個方法傳入了一個名為「savedInstanceState」 的Bundle 型別參數。我们讲解了整段程式,其含意是「覆写bmi类别中公开的onCreate方法。这个「onCreate」方法无回传值型别,而且这个方法传入了一个名为「savedInstanceState」的Bundle型别参数。 現在來看看「onCreate」方法中包含的程式內容。现在来看看「onCreate」方法中包含的程式内容。
第10, 11 行:第10, 11行:
super.onCreate(savedInstanceState);
「super」是關鍵字。 「super」是关键字。 代表著這個「Bmi」 類別的上層類別(Activity)。代表着这个「Bmi」类别的上层类别(Activity)。「super.onCreate(savedInstanceState);」的意思就是:「執行Activity 類別中onCreate 方法的內容」。 「super.onCreate(savedInstanceState);」的意思就是:「执行Activity类别中onCreate方法的内容」。 這麼做的目的是什麼呢?这么做的目的是什么呢?
Google Android 將其應用程式的介面稱為視圖(View),而負責控制各種動作行為的程式主體(Controller),則稱為活動(Activity)。 Google Android将其应用程式的介面称为视图(View),而负责控制各种动作行为的程式主体(Controller),则称为活动(Activity)。 因此一個Android 應用程式,必定會對應到一個以上的Activity。因此一个Android应用程式,必定会对应到一个以上的Activity。 「onCreate」 方法則是每個Activity 類別初始化時都會去呼叫的方法。 「onCreate」方法则是每个Activity类别初始化时都会去呼叫的方法。 我們想做的事,是保持原本「onCreate」 方法預設的動作,然後在其中加入我們想要的內容。我们想做的事,是保持原本「onCreate」方法预设的动作,然后在其中加入我们想要的内容。
而Android 產生的程式預設卻覆寫(@Overwirte)了「Bmi」 類別的「onCreate」 方法。而Android产生的程式预设却覆写(@Overwirte)了「Bmi」类别的「onCreate」方法。 原本繼承自「Activity」類別的「onCreate」方法,其原本內容都被覆蓋掉了。原本继承自「Activity」类别的「onCreate」方法,其原本内容都被覆盖掉了。 因此想將原本的「onCreate」方法內容保留,並在其中加入我們的內容的話,就要使用「super」語句。因此想将原本的「onCreate」方法内容保留,并在其中加入我们的内容的话,就要使用「super」语句。 當 程式運行到我們覆寫的「onCreate」 方法時,透過「super.onCreate(savedInstanceState);」語句,會先將原本「Activity」類別中的 「onCreate」方法執行一次,然後再執行我們覆寫的「onCreate」方法裡面其他的程式內容。当程式运行到我们覆写的 「onCreate」方法时,透过「super.onCreate(savedInstanceState);」语句,会先将原本「Activity」类 别中的「onCreate」方法执行一次,然后再执行我们覆写的「onCreate」方法里面其他的程式内容。
我們要執行原本的「onCreate」 方法時,仍然需要提供原本「onCreate」方法所需的傳入參數。我们要执行原本的「onCreate」方法时,仍然需要提供原本「onCreate」方法所需的传入参数。 因此「super.onCreate(savedInstanceState);」語句中,我們將「savedInstanceState」這個參數傳入原本的「onCreate」函式中。因此「super.onCreate(savedInstanceState);」语句中,我们将「savedInstanceState」这个参数传入原本的「onCreate」函式中。 「savedInstanceState」是我們在「public void onCreate(Bundle savedInstanceState)」語句中所宣告的傳入參數。 「savedInstanceState」是我们在「public void onCreate(Bundle savedInstanceState)」语句中所宣告的传入参数。
setContentView(R.layout.main);
透過螢幕顯示的各種元素是按照介面層次結構來描述的。透过萤幕显示的各种元素是按照介面层次结构来描述的。 要將一個顯示元素的層次結構轉換顯示到一個螢幕上,Activity 會呼叫它用來設定View 的「setContentView」 方法,並傳入想引用的XML 描述文件。要将一个显示元素的层次结构转换显示到一个萤幕上,Activity会呼叫它用来设定View的「setContentView」方法,并传入想引用的XML描述文件。 當Activity 被啟動並需要顯示到螢幕上時,系統會通知Activity,並根據引用的XML 文件敘述來描繪出使用者介面。当Activity被启动并需要显示到萤幕上时,系统会通知Activity,并根据引用的XML文件叙述来描绘出使用者介面。 上一章中我們定義好的res/layout/main.xml 描述檔,就是透過這個機制繪出到螢幕上。上一章中我们定义好的res/layout/main.xml描述档,就是透过这个机制绘出到萤幕上。
setContentView 方法也可以在Activity 類別中找到。 setContentView方法也可以在Activity类别中找到。
你可能也注意到「setContentView」 方法確實是透過「R.layout.main」來引用XML 文件描述檔的資源,而不是直接透過res 目錄來引用。你可能也注意到「setContentView」方法确实是透过「R.layout.main」来引用XML文件描述档的资源,而不是直接透过res目录来引用。