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分析