AndroidLogic 解读程序流程 接着要观察主要程序逻辑的内容。打开 "src/com/demo/android/bmi" 目录下的 "Bmi.java"档桉,Eclipse+Android 开发工具已经帮我们预先建立好了基本的程序逻辑。其预设的内容如下: 代码: 1 package com.demo.android.bmi; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 6 public class Bmi extends Activity { 7 /** Called when the activity is first created. */ 8 @Override 9 public void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.main); 12 } 13 } 讲解 比起什么标签都对称的 XML 介面描述档来说,这个以 Java 程序语言写成的档桉虽然篇幅短,但反而要难读得多。 我们将程序直接拆开,分成几个部份来讲解这个"Bmi.java" 档桉的内容: 第 1 行: 代码: package com.demo.android.bmi; 这 一行的作用是指出这个档桉所在的名称空间。"package"(包)是其关键字。使用名称空间的原因是程序一旦扩展到扩展到某个大小,程序中的变数名称、 方法名称、类别名称难免重複, 这时就可以将定义的名称区隔管理在 package 下,以避免相互冲突的情形发生。Java 的 package 设计成与档桉系统结构相对应,如我们的 package 设定是 "package com.demo.android.bmi",则这个类别就该在指定目录的"com/demo/android/bmi"路径下可以找到。 同时也别忘了 Java 程序语言每段叙述语句的结尾处,与大部分的程序语言一样需加上一个分号";",以表示一行程序叙述的结束。 第 3,4 行: 代码: import android.app.Activity; import android.os.Bundle; 程 序中预设导入了 "android.app.Activity"跟"android.os.Bundle"两个 Package,在所有的 Android 应用程序中都会用到这两个 Package。"import"(导入)是用作导入 Package 的关键字。在 Java 语言中,使用到任何 API 前都要事先导入相对应的 Package。我们马上将学到这两个 Package 的用途。 Android 支援的 Package 与标准的 Java(j2se) 不尽相同。在写 Android 应用程序时,你偶而可能需要参考可用的 API 列表,以确认使用到的 Package 是否有内建支援。后续章节中也将讲解如何透过新增"jar"档来呼叫额外的 Package。 完整的 API 可查阅官方的 package 列表: http://code.google.com/android/reference/packages.html 第 6,13 行: 代码: public class Bmi extends Activity { } 第6行开始了程序的主体。其组成是这样的: 代码: public class Bmi "Bmi"是这个类别的名称。"class"则是用作宣告类别关键字。"public"关键字是用来修饰"Bmi"这个类别。表示"Bmi"是个"公开"的类别,可以从 package 外部取用。 "public class Bmi"后面再加上"extends Activity"叙述,则表示 "Bmi"这个类别的功能、型别等全继承自"Activity"类别。"extends"是继承(Inherit)类别的关键字。"Activity"是 来自于我们在第3行刚导入的Package。 因此整句话的含意即:"宣告一个公开的 Bmi 类别。这个 Bmi 类别继承了程序开头导入的 Activity 类别"。 "{}"大括号规范了一个程序区块。大括号中的程序表达的这个程序区块的主要内容。 第 7 行: 代码: /** Called when the activity is first created. */ 第 7 行提供了位于其下的函式的注释。"/* */" 是 Java 语言的多行注解符号,位于其中的文字内容不会被编译。"/*"叙述后多出来的一个"*"号被视为内文。顺便提醒一下,Java 程序语言中两个斜线"//"表示的是单行注解符号。单行注解符号"//"与多行注解符号"/* */"不同的地方是,只有与"//"符号同行的文字才不会被编译。 第 8-9, 12 行: 代码: @Override public void onCreate(Bundle savedInstanceState) { } 第9行开始了这个方法(Method)的主体。其组成是这样的: 代码: public void onCreate(Bundle savedInstanceState) { } "onCreate"是这个方法的名称。"void"则是宣告了这个方法的回传值的型别(type)。"public"关键字是用来修饰"onCreate"这个方法。表示"onCreate"是个"公开"的方法,可以由 bmi 类别外部取用。 方法的回传值的型别,即是这个方法的型别。"onCreate"这个方法使用"void"型别,表示"onCreate"这个方法不需回传值。 同 时,这个方法传入了一个名为"savedInstanceState"的"Bundle"型别参数,"Bundle"型别正是来自我们前面所导入的 Package 之一。我们并不需要知道太多"Bundle"型别或"savedInstanceState"实体的细节,只要知道"Bundle"的内容与手机平台的记 忆体管理有关。 当 Android 应用程序启动、换到背景等待、关闭时,都会用到 "savedInstanceState"这个实体来处理记忆体相关的事宜。当然,你也可以用其他名称来代替它。还好"onCreate"这个方法永远都 是传入"Bundle savedInstanceState"这个参数,写应用程序时只要正确照规定传入即可,你可以不用太去在意它。 给对 Bundle 是什么有兴趣的读者: "Bundle"可以保存程序上一次关闭(冻结)时的状态。你可以透过覆写 onFreeze 方法(与 onCreate 方法的作用类似) 来保存冻结前的状态。 当程序启动(Activity 重新初始化)时,会再次呼叫 onCreate 方法,你就能从 savedInstanceState 中得到前一次冻结的状态。我们也可以透过"Bundle"来将这个 Activity 的内容传到下一个 Activity 中。 之后讲 Activity 时,也会讲解 onCreate/onFreeze 等方法的关系。 "{}"大括号规范了一个程序区块。大括号中的程序表达 onCreate 这个程序区块的主要内容。 代码: @Override public void onCreate(Bundle savedInstanceState) 从 前面的讲解中,我们学到了在任何一个 Android 专桉目录里,只要打开"Referenced Libraries"目录的"android.app" 分类,都可以找到"Activity.class"这个类别。现在我们再深入一些查看"Activity.class" 类别。你要做的,只是依照图示,找到 Android 工具中的"Referenced Libraries" 目录,从"android.app"分类里找到"Activity.class"类别,并按下"Activity.class"类别左侧的三角形图示,如 此即可展开这个类别的属性/方法列表。 我们在Activity类别的属性/方法列表中,发现了现在正要讲解的 onCreate 方法(Method)。 因为"bmi" 类别继承自 Activity 类别,所以预设"bmi" 类别中其实已经有"onCreate"方法了。 事 实上,"onCreate" 方法正是每个 Activity 类别初始化时都会去呼叫的方法。"@"开头的语句表示装饰子(decorator)语句,"@Override"语句的作用是告诉程序我们要覆写这 个"onCreate"方法。当我们打开程序时,程序不再使用从"bmi" 类别中继承来的"onCreate"方法,而是使用我们在程序中自订的行为。 代码: @Override public void onCreate(Bundle savedInstanceState) { } 我 们讲解了整段程序,其含意是"覆写 bmi 类别中公开的 onCreate 方法。这个 "onCreate"方法无回传值型别,而且这个方法传入了一个名为 "savedInstanceState" 的 Bundle 型别参数。现在来看看"onCreate"方法中包含的程序内容。 第 10, 11 行: 代码: super.onCreate(savedInstanceState); "super"是关键字。代表着这个 "Bmi"类别的上层类别(Activity)。"super.onCreate(savedInstanceState);"的意思就是:"执行 Activity 类别中 onCreate 方法的内容"。这麽做的目的是什么呢? Google Android 将其应用程序的介面称为视图(View),而负责控制各种动作行为的程序主体(Controller),则称为活动(Activity)。因此一个 Android 应用程序,必定会对应到一个以上的 Activity。 "onCreate" 方法则是每个 Activity 类别初始化时都会去呼叫的方法。我们想做的事,是保持原本"onCreate" 方法预设的动作,然后在其中加入我们想要的内容。 而 Android 产生的程序预设却覆载(@Override)了"Bmi" 类别的"onCreate" 方法。原本继承自"Activity"类别的"onCreate"方法,其原本内容都被覆载掉了。因此想将原本的"onCreate"方法内容保留,并在 其中加入我们的内容的话,就要使用"super"语句。当程序运行到我们覆写的"onCreate"方法时,透 过"super.onCreate(savedInstanceState);"语句,会先将原本"Activity"类别中的"onCreate"方法 执行一次,然后再执行我们覆写的"onCreate"方法里面其他的程序内容。 我们要执行原本的"onCreate"方法时,仍然需要提 供原本"onCreate"方法所需的传入参数。因此"super.onCreate(savedInstanceState);"语句中,我们 将"savedInstanceState"这个参数传入原本的"onCreate"函式中。"savedInstanceState"是我们 在"public void onCreate(Bundle savedInstanceState)"语句中所宣告的传入参数。 代码: setContentView(R.layout.main); 透 过萤幕显示的各种元素是按照介面层次结构来描述的。要将一个显示元素的层次结构转换显示到一个萤幕上,Activity 会呼叫它用来设定 View 的 "setContentView" 方法,并传入想引用的 XML 描述文件。当 Activity 被启动并需要显示到萤幕上时,系统会通知 Activity,并根据引用的 XML 文件叙述来描绘出使用者介面。上一章中我们定义好的 res/layout/main.xml 描述档,就是透过这个机制绘出到萤幕上。 setContentView 方法也可以在 Activity 类别中找到。 你可能也注意到 "setContentView" 方法确实是透过 "R.layout.main"来引用 XML 文件描述档的资源,而不是直接透过 res 目录来引用。 来源:http://code.google.com/p/androidbmi/wiki/AndroidLogic |
文章评论(0条评论)
登录后参与讨论