第二章 Hello,Android!
2.1 创建第一个Android 项目
1. 启动Eclipse --> File --> New --> Project
2. 选中“Android” 目录下的“Android Project” 选项,单击“Next” 按钮创建Android 项目。
A. Project name : 项目名称
B. Build Target : 选择版本
C. Application name : 应用名称(安装手机上显示的名字)
D. Package name : 包名
E. Create Activity : 主Activity 类名
F. Min SDK Version : (可省略不填)最低运行版本号,“4” 对应SDK 1.6
2.2 剖析Android Project 结构
1. src 目录用来存放项目代码(.java)。
2. gen 目录存放R.java 文件。
A. R.java 文件时该项目所有资源的索引文件。
B. R.java 文件在建立项目时自动生成。
C. R.java 文件属于只读模式,不能更改。
D. R 类中包含很多静态类,其中这些静态类的名称都与res 目录下的资源目录一一对应。
E. 项目中新加资源,刷新项目,则R 资源文件就会更新,为新添加的资源生成一个新的索引。
F. R 文件的作用和优点:
① 在项目中使用资源可以使用R 文件所生成的索引(R 文件会将所有资源生成索引)。
② 编译器在对项目编译的时候会检查R 文件中的资源是否被使用,没有被使用的资源,编辑器不会编译到应用中,从而节省在手机中占用的内存。
3. Android (Library) 目录:此目录下的“android.jar” 文件指向的是 Android SDK,是开发Android 应用程序所用的所有API函数库。
⑴ assets 目录是用来存放引用的外部资源,此目录与res目录最大的区别在于:res 路径下的资源文件都会在R 资源文件中自动生成对应资源ID,而assets 目录下资源则不会。
4. res 目录是用来存放项目中用到的资源文件(有5个默认子目录,1.5及以下版本默认3个子目录,为了兼容不同机型屏幕将dreawable 一分为三)。
⑴ drawable-hdpi、drawable-ldpi、drawable-mdpi 三个子目录(1.5以前是drawable一个子目录)是用来存放图片资源的。
① drawable-hdpi : 存放高分辨率图片,如WVGA(480X800)、FWVGA(480X854);
② drawable-mdpi : 存放中等分辨率图片,如HVGA(320X480);
③ drawable-ldpi : 存放低分辨率图片,如QVGA(240X320);
④ 创建的虚拟设备设置的一些属性和参数,会使模拟器自动获取对应目录下的资源。如果不小心放错位置了,也没关系,当Android OS 在对应drawable 目录下找不到资源时,会从其他两个子目录下进行寻找。
⑵ 子目录layout 用来存放布局文件以及xml格式的描述文件。
⑶ 子目录value 设置项目需要显示的各种文字,也可以存放多个*.xml 文件,存放不同类型的数据(如colors.xml 字体颜色、styles.xml 显示类型 等等)。Android 手机系统会根据手机系统语言默认使用程序中对应的目录资源文件管理(value-en-rUS 英文;value-zh-rTW 繁体;values-zh-rCN 简体)。
⑷ res 中除了默认目录,还有很多放置资源的自定义目录,比如raw(声音) 等。
⑸ 在Android 系统中,图片、声音等资源名称不能使用大写英文字母!
5. AndroidManifest.xml 是当前项目的配置文件,其包含编码格式、应用的icon、程序的版本号以及制定该程序使用到的服务等。
⑴ 如果新添加一个Activity,就需要再这个文件中进行相应配置,然后才能调用此Activity,设定Activity 的属性页在此设定。
6. default.properties 是记录项目工程的环境信息。
注意:使用xml 来进行开发,一旦layout 布局文件或sting.xml 文件需要更新应用,无需再去java 源代码中修改和更新数据,而是直接对其layout 和string.xml 进行修改和更新就可以了。(更好维护和更新)
2.3 AndroidManifest.xml 与应用程序功能组件
1. 在每个Android 应用程序中都必须具备 AndroidManifest.xml 这个文件,它定义了该程序的主要功能、处理的信息,以及执行的动作等等。
2. AndroidManifest.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ray.yar"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".aTest001"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2.3.1 AndroidManifest 的 xml 语法层次:
| 1层 | ||||
| <manifest> | 2层 | |||
| <application> | 3层 | |||
| <uses-permission> | <activity> | 4层 | ||
| <permission> | <receiver> | <intent-filter> | 5层 | |
| <instrumentation> | <service> | <meta-data> | <action> | |
| <uses-sdk> | <provider> | <category> | ||
| <data> |
在上面的层次图中,在同一层的标签都是按照位置关系写在了一起,不同层的标签并不都是包含关系。
⑴ (最外层)<mainfest> 定义了软件的属性,如包路径、程序的版本、版次等等。
⑵ (第2层)<application> 定义应用程序属性及功能;如android:icon 指定了应用的icon 图标,android:label 定义了应用程序的名称,并且声明功能<activity> 活动。
⑶ (第3层)定义功能组件,如<activity> 活动、<receiver> 意图与广播接受、<service> 服务、<provider> 属性(内容)提供者,都必须定义在<application> 中,所以这里定义了<activity> 活动类以及活动类名称。
⑷ (第4层)<intent-filter> 其功能如一个过滤器,后文将详细解释。
⑸ (第5层)<action> 定义了意图动作的类型;<category> 是意图的属性,这里的值android.intent.category.LAUNCHER 表示启动应用程序的时候,意图将该acctivity 显示在屏幕上;这种启动程序的意图活动只能有一个。
【4种应用程序的功能组件】
2.3.2 <activity> -- Activity(活动)
Android 中一个activity 就是一个用户界面(如:手机拨号界面、通讯录界面等)。在应用程序中可以有一个或多个活动,但如果新建了一个活动,必须在AndroidManifest.xml 中进行声明。
2.3.3 <receiver> -- Intent(意图)与Broacast Receiver (广播接收)
① 意图:是描述动作的机制,在Android 手机中几乎都有意图阶段(如:当天有一个“发出一条信息”的意图Intent,这时候如果应用程序需要发送信息,调用该意图即可)。
② 广播接收:在应用程序中注册一个活动来处理意图,接收意图称为Broadcast Receiver(广播接收)。
③ 因为在Android 中有很多的意图,为了使接受具有针对性,可以在<intent-filter> 中指定接受意图的动作<action>,因此<intent-filter> 的作用就是一个意图的过滤器。
2.3.4 <service> -- 服务
服务:应用程序在后台运行的任务。无需显示界面、也不必跟用户进行交互,但是又需要长时间在后台进行运行(例如后台播放音乐)。
2.3.5 <provider>-- Content Provider(内容提供者)
带有内容提供功能的应用程序所进行的动作是让使用者可以保存他们的信息或文件,例如:Android 手机联系人程序提供了一个内容提供者,任何要使用联系人信息的应用程序都可以共享内容提供者的所有信息,比如联系人的姓名、电话号、地址等等。
2.3.6 除了以上应用功能组件之外,Android 对某些关键操作和访问都是有权限来设置的。
例如:一个应用程序要将一些数据保存到手机的SDcard 中,那么就需要在AndroidManifest 中设置添加写入SD 卡权限,其语法标签是:<uses-permisson>。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ray.yar"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".aTest001"
android:label="@string/app_name">
... // 代码省略
</activity>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
<uses-permission> 与<application> 在AndroidManifest 语法中属于同一层次。
2.4 运行Android 项目(启动Android 模拟器)
运行Android 项目的方式概括起来有两种:
1. 直接运行Android 项目
Eclipse 主界面上,在“Package Explorer” 窗口中找到需要运行的项目,右键项目名称 --> Run As --> Run Configurations 进入运行配置界面。
① Run Configurations 窗口的Android 标签页中单击“Browse...” 按钮,选中需要运行的项目。
② 然后进入“Target” 标签选择运行设备的运行方式:手动(Manual)和自动(Automatic)两种,然后勾选自己创建的设备
③ 最后单击“Run” 按钮即可。
④ 再次运行项目时,不必进入“Run Configurations” 来重新设置,只需要在“Package Explorer” 窗口中右键单击项目名 --> Run As --> Android Application 即可执行应用。
2. 先启动模拟器,再运行Android 项目
① 在SDK&AVD 管理界面,选择已经建立好的AVD,单击“Start” 按钮即可启动模拟器(第一次启动有点慢)。
注意:因为Android 是向下兼容,所以运行项目的时候,前提是已经创建了高于或等于当前项目的运行版本的模拟器,否则在“Target” 设备一栏中不会显示任何设备。
② 在模拟器中找到想要运行的项目即可。
2.5 详解第一个Android 项目源码
1. 运行“MyFirstProject” ,手机屏幕上默认显示“手机状态栏”和“应用名称”。
2. aTest001.java 源码:
package ray.yar; // 本类所在的包路径。
import android.app.Activity; // 引入相关类。
import android.os.Bundle;
public class aTest001 extends Activity { // 创建一个类,并且集成Activity 类。
/** Called when the activity is first created. */ // "@Override" 表示onCreate() 函数(方法),
@Override // 是重写Activity 中的onCreate() 方法(否则认为是开发者自定义的函数)。
public void onCreate(Bundle savedInstanceState) { // 重写了Activity 生命周期中的onCreate() 方法。
super.onCreate(savedInstanceState); // 调用父类的onCreate() 方法。
setContentView(R.layout.main); // 利用当前的Activity 类的setContentView() 来显示布局。
}
}
3. main.xml 源码:
<?xml version="1.0" encoding="utf-8"?> // 描述xml 的版本以及编码格式
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" // 定于布局形式,LinearLayout 为线性布局。
android:orientation="vertical" // 设置布局位置放置的类型,“vertical” 垂直放置。
android:layout_width="fill_parent" // 设置布局的宽为填充类型,即填充屏幕
android:layout_height="fill_parent" // 设置布局的高为填充屏幕
> // “>”布局基础属性结束(非布局结束)
<TextView // 在布局中添加TextView 组件
android:layout_width="fill_parent" // 设置TextView 组件的宽为填充类型
android:layout_height="wrap_content" // 设置TextView 组件的高为自适应类型,根据内容高度自动调整
android:text="@string/hello" // 设置TextView 组件的文本内容。
/> // "/>" 表示TextView 设置结束,也可写成“></TextView>”
</LinearLayout> // 整个线性布局设置结束。
4. 对于布局、组件等属性的设置格式一般为:
<布局/组件名称
android:属性="属性类型"
...
/>
5. main.xml 源码中 "@string/hello” 表示索引string.xml 中定义的字符串,"hello" 是在string.xml 中定义字符串的变量名。
① main.xml中:android:text="@string/hello"
② string.xml中:<string name="hello">Hello World, MainActivity!</string>
2.6 Activity 生命周期
Activity 主要负责创建和显示窗口(一个Activity 可以理解为一个显示的屏幕);在Android 的应用中不是仅有一个Activity,而是可以有多个Activity 存在。
2.6.1 单个Activity 的生命周期
⑴ Activity 生命周期中的7个函数:
① onCreate: Activity 初次创建时被调用(一般在这里创建view、初始化布局信息、将数据绑定到list以及设置监听器等等)。如果Activity 首次创建,本方法将调用onStart();如果Activity 是停止后重新显示,则调用onRestart()。
② onStart: 当Activity 对用户即将可见的时候被调用,气候调用onResume()。
③ onRestart: 当Activity 停止后重新显示的时候会被调用,然后调用onStart()。
④ onResume: 当用户能在界面中进行操作的时候被调用。
⑤ onPause: 当系统要启动一个其他的Activity 时调用(其他的activity 显示之前),这个方法被用来停止动画和其他占用CPU资源的事。所以在这里应该提交保存那些持久数据,这些数据可以再onResume() 方法中读出。
⑥ onStop: 当另外一个Activity 恢复并遮盖住当前Activity,导致其对用户不再可见时调用。一个新的Activity 启动、其它Activity 被切换至前景、当前Activity 被销毁时都会调用此函数。如果当Activity 重新回到前景与用户交互时会调用onRestart(),如果Activity 将退出则调用 onDestory()。
⑦ onDestory: 在当前的Activity 被销毁前所调用的最后一个方法,当进程终止时调用(对Activity 直接调用Finish 方法或者系统为了节省空间而临时销毁此Activity 的实例)。
⑵ Activity 生命周期图:

⑶ 切入后台 "Back” 和 "Home" 的区别:
| 操作 | "Back"方式 | "Home"方式 |
| 将Activity切入后台 |
onPause onStop onDestroy |
onPause onStop |
| 将Activity从后台重新回到前台 |
onCreate onStart onResume |
onRestart onStart onResume |
2.6.2 多个Activity 的生命周期
当存在两个(或多个)Activity 的时候,每个Activity 的生命周期状态变化。
修改项目,添加一个button的按钮,单击按钮打开另一个Activity(OtherActivity)。
⑴ 在MainActivity 中,单击button 按钮:
MainActivity --> onPause
OtherActivity --> onStart
OtherActivity --> onResume
MainActivity --> onStop
⑵ 当OtherActivity 打开之后,单击手机上的"Back" 按钮:
OtherActivity --> onPause
MainActivity --> onRestart
MainActivity --> onStart
MainActivity --> onResume
OtherActivity --> onStop
OtherActivity --> onDestroy
⑶ 每个Activity 都可以设置它的模式:A. 默认 B. Dialog(对话框)
⑷ Activity 之间进行跳转时还需要注意:当打开另外一个Activity,我们要清楚另外一个Activity 是否能完全遮挡住当前的Activity 视图,具体区别:
| Yes (默认主题模式) | No (Dialog主题模式) | |
| B的视图是否能完全覆盖A |
MainActivity --> onPause OtherActivity --> onStart OtherActivity --> onResume MainActivity --> onStop |
MainActivity --> onPause OtherActivity --> onStart OtherActivity --> onResume |
以上两种状态是从一个Activity 跳转到另外一个Activity 的时候,并没有在代码中手动关闭第一个Activity。
再来看看当打开另外一个Activity 的时候,手动关闭之前的Activity 时,两个Activity 的生命周期(在一个Activity 中,只要调用finish() 函数,即可退出当前Activity)。
⑴ 在Mainactivity 中单击"Button" 按钮:
MainActivity --> onPause
OtherActivity --> onStart
OtherActivity --> onResume
MainActivity --> onStop
MainActivity --> onDestroy
说明:区别很明显,在打开Otheractivity 时,如果程序中手工关闭第一个MainActivity,那么在打开另一个Activity 之后,MainActivity在调用onStop 之后会多调用一个onDestory 的状态。
⑵ 当Otheractivity 打开之后,单击手机上的"Back" 按钮:
OtherActivity --> onPause
OtherActivity --> onStop
OtherActivity --> onDestroy
说明:因为MainActivity 在Otheractivity 之后就关闭掉了,所以程序中只有OtherActivity存在,这个时候单击"Back" 就如同单个Activity的"Back" 执行的生命周期流程。
2.6.3 Android OS 管理Activity 的方式
对于Activity 的管理,Android 底层是用堆栈来存放Activity 的(打开的Activity 放在栈顶,显示在屏幕最上层,而之前Activity 则会被新打开的Activity 覆盖)。
例如:一个程序正在运行,突然手机来电,Android 接受到来电广播后会打开一个接听电话的Activity 放入堆栈的栈顶,这样一来运行的程序就会被接听电话的Activity 所覆盖。
2.7 Android 开发常见问题
2.7.1 Android SDK 与 Google APIs 创建Emulator 的区别:
(每个SDK版本都对应一个Google APIs) 其实两种形式创建的模拟器是没有区别的,只是Googel APIs 中,Google 把自己提供的程序,如:Google Map 放在了Google APIs 创建出来的模拟器中。因此,如果开发Google Map 等一些Google 专属的应用程序,就必须选用 Google APIs 创建出的模拟器。
2.7.2 将Android 项目导入Eclipse
从外部导入一个Android Project,有两种方式:新建Android 项目导入 和 直接导入。
1. 新建Android 项目导入方式
新建项目 --> 新建项目配置 --> 选中“Create project from existing source” 单选按钮,然后单击“Browse..." 按钮选择项目路径,最后单击“Finish” 即可。
2. 直接导入方式
单击Eclipse 菜单栏上的“File —> Import” 进入导入方式选择界面 --> 选中“Existing Project into Workspace” 选项,然后单击“Next” 按钮进入导入项目界面 --> 单击“Browse...” 按钮选择项目路径即可(当前界面“Copy projects into workspace” 复选框,选中表示将导入的项目拷贝到Eclipse 工作目录中,不选中则默认修改的是导入的项目)。
2.7.3 在Eclipse 中显示Android 开发环境下常用的View 窗口
在Eclipse 菜单一栏中单击“Windows —> Show View —> Other ”打开“Show View ” 窗口
单击Android 展开列表项,常用到的视图有3个:Devices、File Explorer、LogCat。
① "Devices" 窗口:
A. 小虫子:单击此图标即可进入Debug 模式进行调试;
B. 红底白字stop:单击此图标即消亡程序;
C. 照相机:截取当前模拟器/真机屏幕。
② "File Explorer" 视图:
A. 箭头向外:当选中文件时,单击此图标导出文件。
B. 箭头指向手机:当选中文件时,单击此图标导入文件。
C. 横杠:当选中文件时,单击此图标表示删除此文件。
③ "Logcat" 窗口:用于显示项目运行时的打印信息等。
2.7.4 在Eclipse 中利用打印语句(Log)调试Android 程序。
Android 中一般常用的打印语句有五种:
① Log.v(黑色):任何消息都会输出,一般都利用这个打印来进行观察程序运行状况。
② Log.i(绿色):输出的是提示性的信息。
③ Log.d(蓝色):只输出Debug 的信息。
④ Log.w(黄色):输出警告信息。
⑤ Log.e(红色):输出错误信息。
问题:有时候会发现程序明明写了输出余军,而且也确实执行到,可是“LogCat” 视图中就是不显示打印的信息。
解决办法:在“Devices” 视图中单击运行的程序,“LogCat” 视图中就会显示打印的信息了。
分析:这是因为“LogCat” 默认显示输出的是整个模拟器的运行状态,只有在“Devices” 视图中单击(指定)到程序上,“LogCat” 视图才会输出程序的打印信息。
2.7.5 在Eclipse 中真机运行Android 项目
⑴ 将Android 手机通过USB 线连接到电脑上,然后在手机上选中“USB 调试”
⑵ 在电脑上安装对应手机的驱动(这样Eclipse 的Divices 视图中就会显示出真机设备了)。
⑶ 如果想运行项目在手机上,只要在“Run Configurations” 窗口下的“Trget” 标签下选中“Manual(手动选择运行设备)”,然后在Run 的时候,手机设备如果正常连接,将会弹出“Android Device Chooser” 窗口。
⑷ 在“Android Device Chooser” 窗口中,选中真机设备,最后单击“OK” 按钮运行。
2.7.6 设置Android Emulator(模拟器) 系统语言为中文
⑴ 默认模拟器系统语言为英语。
⑵ 设置系统语言:
单击运行设备上的“Menu —> Settings —> Locale & test —> Select locale” 菜单项,然后选择“简体中文”即可设置系统语言。
2.7.7 切换模拟器的输入法:
⑴ 单击输入空间知道弹出“Edit text” 对话框后释放鼠标。
⑵ 然后单击“Input Method” 菜单进入选择输入法窗口界面。
⑶ 选中“谷歌拼音输入法” 即可。
2.7.8 模拟器中创建SD Card:
在之前利用AVD创建Android 模拟器的时候(绿机器人--> new),稍微调整配置就可以了。
A. 输入SDcard 大小(至少9M),这里是以MB为单位。
B. 在“Hardware” 列表框下单击“NEW” 按钮,添加“SD Card support” —— SD Card 硬件支持。
2.7.9 模拟器横竖屏切换
A. Ctrl + F11:横竖屏切换
B. Ctrl + F12:横竖屏切换(效果同A)
2.7.10 打包Android 项目

浙公网安备 33010602011771号