1.6 Android程序结构分析
在前面已经完成一个最简单的Android手机程序开发,并且在模拟器上运行通过。但是,大家脑海中一定存在很多疑问,Android程序是怎样组织、如何运行的呢?
下面根据前面创建的HelloWorld来分析一下Android应用程序的结构。虽然这个例子简单,也没有写任何代码,但是 “麻省虽小,五脏俱全”,可以从中对Android应用程序有一个整体的认识。
在Eclipse集成开发环境的“包资源管理器”中,展开“HelloWorld”项目,如图1-36所示。
● src目录:源文件文件夹。
● gen目录:保存自动生成的R资源索引类文件夹。
● assets目录:保存原始资源类文件的文件夹。
● res目录:资源文件夹。
● AndroidManifest.xml文件:Android应用程序的配置清单文件。
这些目录和文件构成了Android智能手机程序的框架。下面分别介绍各个部分的含义和作用。
1.6.1 src目录
在src目录下包含了应用程序的源文件,这里为MainActivity.java文件,打开该文件,其代码为:
package com.example.e1; //包名称 import android.os.Bundle; import android.app.Activity; //导入Android程序包 import android.view.Menu; public class MainActivity extends Activity //MainActivity类 { @Override public void onCreate(Bundle savedInstanceState) //重载onCreate { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public boolean onCreateOptionsMenu(Menu menu) //创建菜单 { getMenuInflater().inflate(R.menu.main, menu); return true; } }
在以上代码中,创建了一个MainActivity类,其继承了Activity类,也就是说MainActivity类是Activity的子类。在此,重载了onCreate方法。在onCreate方法中,首先调用父类构造应运,然后调用onCreateOptionsMenu方法来创建菜单项。
1.6.2 gen目录
在gen目录下包含了自动生成的R资源索引文件,这里为R.java。打开该文件,其代码为:
//这个类的数据资源是自动生成的,不可手动修改 package com.example.e1; //包名称 public final class R { public static final class attr //R资源索引类 { } public static final class drawable{ //图片属性 public static final int ic_action_search=0x7f020000; public static final int ic_launcher=0x7f020001; } public static final class id { public static final int menu_settings=0x7f070000; } public static final class layout{ //布局文件 public static final int main=0x7f030000; } public static final class menu{ //菜单 public static final int main=0x7f060000; } public static final class string{ //字符串 public static final int app_name=0x7f040000; public static final int hello_world=0x7f040001; public static final int menu_settings=0x7f040002; public static final int title_activity_main=0x7f040003; } public static final class style{ //类型 public static final int AppTheme=0x7f050000; } }
这里的R.java文件为只读模式,由Eclipse自动添加修改,用户无须进行修改。仔细观察该文件,这里相当于定义了很多不同类型的常量,包括属性、图片、布局文件和字符串。这些常量名称与res文件夹中的文件名完全相同。也就是说,R.java文件中的常量是该项目中res文件夹中所有资源的索引。通过这些索引,Android程序可以很快地引用这些资源。
1.6.3 res目录和assets目录
在res目录下包含了该项目所使用到的资源文件,这里面的每一个文件或者资源都将在R.java文件中进行索引定义。主要包括如下几类。
● 图片文件:分别提供了高分辨率(drawable-hdpi)、中分辨率(darawable-mdpi)和低分辨率(drawable-ldpi)的图片文件。
● 布局文件:在layout目录下,默认只有一个main.xml文件,用户也可以添加更多的布局文件。
● 字符串:在value目录下的strings.xml文件中。
打开main.xml布局文件,代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView //文本框控件 android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/hello_world" //显示内容 tools:context=".MainActivity" /> </RelativeLayout>
在该布局文件中,首先定义了采用相对布局,内部只有一个文本框控件。这个控件显示的内容引用了string文件中的hello_world变量。因此,再看一下strings.xml文件,代码如下:
<resources> <string name="app_name">E1</string> <string name="hello_world">Hello world!</string> //hello_world字符串 <string name="menu_settings">Settings</string> //title_activity_main字符串 <string name="title_activity_main">MainActivity</string> </resources>
这里定义了两个字符串,hello字符串的内容为“Hello world!”,这正是该程序运行界面上显示的内容;menu_settings字符串的内容为“MainActivity”,这正是该程序的标题上显示的内容。
assets目录同样用来存放应用程序用到的资源文件,只不过assets目录中存放的资源不会在R.java文件中进行索引定义。
1.6.4 AndroidManifest.xml文件
在文件AndroidManifest.xml中包含了该项目中所使用的Activity、Service、Receiver,看下面“HelloWorld”项目中的AndroidManfest.xml文件,其代码为:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.e1" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
从上述代码中,intent-filters描述了Activity启动的位置和时间。每当一个Activity(或者操作系统)要执行一个操作时,它将创建出一个Intent的对象,这个Intent对象能承载的信息可描述用户想做什么,用户想处理什么数据,数据的类型,以及一些其他信息。而Android则会和每个Application所暴露的intent-filter的数据进行比较,找到最合适Activity来处理调用者所指定的数据和操作。下面仔细分析AndroidManifest.xml文件,如表1-3所示。
表1-3 AndroidManifest.xml分析