Android应用程序主要由资源文件和代码文件两部分构成。资源文件以XML格式描述;代码文件主要为Java文件,用于实现业务逻辑。下面通过HelloAndroid项目为例,解析Android应用程序结构。
(1)colors.xml
该文件用于定义颜色常量,默认生成的HelloAndroid项目的colors.xml文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
<color>:定义颜色资源的标签。
<color name="colorPrimary">#3F51B5</color> :定义颜色常量,颜色资源名称为“colorPrimary”,颜色值为3F51B5。
在Android系统中,颜色值可以有#RGB 、#RRGGBB 、#ARGB和#AARRGGBB这4种数据格式。每一种数据形式都为十六进制,必须以“#”开头。其中,R代表红色值,G代表绿色值,B代表蓝色值,A代表透明度。
(2)dimens.xml
该文件用于定义布局常量。默认生成的dimens.xml文件内容如下:
<resources>
<!--Default screen margins,per the Android Design guidelines.-->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
<dimen>:定义尺寸资源的标签。
<dimen name="activity_horizontal_margin">16dp</dimen> :尺寸资源名称为“activity_horizontal_ margin”,值为16dp。
项目中可以使用尺寸资源定义布局或控件的边界、高度和尺寸大小。尺寸单位可以为px(像素)、in(英寸)、mm(毫米)、pt(磅)、dip(与密度无关的像素)和sp(与刻度无关的比例像素)。最常用的尺寸单位为dip和sp。
dip(device independent pixels,设备独立像素):与屏幕密度无关,不同设备有不同的显示效果。一般为了支持WVGA、HVGA和QVGA,推荐使用该单位。屏幕密度为160(每英寸160个像素点)时,1dip=1dx。当屏幕密度变大时,dip与 dx的关系为:dip(value)=(int)(px(value)/1.5+0.5)。如果不使用dip单位,则布局元素显示偏小。dp同dip。
sp(scaled pixels,与刻度无关的比例像素):主要处理字体的大小。与 dp类似,但是可以根据用户的字体大小首选项进行缩放。
(3)strings.xml
该文件用于定义和存储项目中的字符串资源,默认生成的HelloAndroid项目的strings.xml文件内容如下:
<resources>
<string name="app_name">HelloAndroid</string>
</resources>
<resources>:定义资源的标签。
<string name="app_name">HelloAndroid</string> :声明了一个字符串资源,字符串的名称为“app_name”,字符串的内容为“HelloAndroid”。
有很多应用程序,比如微信,当手机语言设置为中文时,微信内部显示为中文。而系统语言设置成英文时,微信的内容实现也变成了英文。让程序适应不同语言环境,适配多种语言,这就称作语言的国际化。Android中之所以将字符串设定为资源,目的就是为了方便实现国际化。
Android中采用XML文件进行界面布局,可将布局界面的代码和业务逻辑控制的Java代码分离开来,使应用程序的结构更加简单清晰。
建立HelloAndroid时,已经创建了activity_main.xml文件,该文件代码如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_depth="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView android:text="Hello World!"
android:layout_width="wrap_content"
android:layout_depth="wrap_content" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> :声明了XML的版本号和编码方式。
<RelativeLayout> :声明本界面采用的布局为RelativeLayout相对布局。该标签下定义了诸如layout_width 、layout_height和paddingLeft等常用属性,相关内容将在本书4.4节中详细介绍。
布局标签下还包括一个<TextView> 的标签,说明在布局中添加了一个文本控件TextView,用于显示“Hello World! ”文字信息。
此处特别说明一点:语句android:paddingLeft="@dimen/activity_horizontal_margin" 中使用了资源的引用。在资源中对另一种资源引用时,一般引用格式为@type/name。其中,@表示对资源的引用;type表示被引用的资源类型,name表示资源名称。资源引用还有另外一种格式@+type/name。两种格式的区别是:前者是已经在R文件中注册的资源,后者是现在新增加的资源,+表示要在R文件中添加对该资源的注册。
Android项目包含一个重要的文件R.java。项目中所有的资源都有一个唯一的ID标识,而且必须在该文件中注册。该文件自动生成,自动维护,程序开发人员不能对其修改,否则可能造成程序错误。
使用Android Studio环境建立的工程,其R.java文件存放的路径如图2-4所示。
打开R.java文件,读者会发现该文件内容很长,可以将各部分展开的内容一一收起(单击编辑区域左侧显示的“−”),如图2-5所示。
图2-4 R.java文件的存放路径
图2-5 R.java文件的基本结构
R.java文件中默认生成了若干个静态内部类。每个静态内部类分别对应着一种资源,如layout静态内部类对应layout目录中的界面文件,mipmap静态内部类对应mipmap目录中的图片文件。大部分的静态内部类是灰色显示的,表明相关资源尚未在程序中引用。
每个静态内部类中的静态常量分别定义一条资源标识符。将R.java中的 layout静态类展开,只截取其中的部分内容,如图2-6所示。语句“public static final int activity_main=0x7f040019; ”中,activity_main对应layout目录下的activity_main.xml布局文件,该文件的资源ID编号为0x7f040019。
图2-6 layout静态类
打开HelloAndroid项目的src目录下的MainActivity.java文件,查看代码,如图2-7所示。
图2-7 MainActivity.java代码
第1行:声明本java文件存放的包名。
第3~4行:引入本文件中使用到的类。
第6行:定义MainActivity类的开始,本类继承于AppCompatActivity类,而这个父类是在第3行中引入的类。
第8行:表明它下面所定义的方法 onCreate()是重载父类的方法。出现@override时,编译器可以自动检测该方法是否在父类中有定义,如果没有定义则会报错,因此可以一定程度上避免方法名称输入错误的可能性。
第9~12行:重载了onCreate()方法,该方法需要传入一个名称为savedInstanceState的Bundle类型的参数。
第10行:调用父类的onCreate()方法。
第11行:调用setContentView()方法,加载activity_main.xml布局文件,实现界面布局的显示。该方法中的参数R.layout.activity_main,表示在代码中引用资源文件。代码中引用资源文件的格式为R.type.name,其中,R表示R.java文件;type表示资源的类型,即在R.java中定义的内部静态类;name表示资源的名称。