官术网_书友最值得收藏!

1.3 Android應(yīng)用程序的結(jié)構(gòu)

1.3.1 Android應(yīng)用程序的代碼組成

Android應(yīng)用程序包含了工程文件、代碼和各種資源,主要由Java語(yǔ)言編寫,每一個(gè)應(yīng)用程序?qū)⒈痪幾g成Android的一個(gè)Java應(yīng)用程序包(*.apk)。

一般情況下,Android應(yīng)用程序由以下4種組件構(gòu)成:

活動(dòng)(Activity);

服務(wù)(Service);

廣播接收器(BroadcastReceiver);

內(nèi)容提供者(ContentProvider)。

一個(gè)Android應(yīng)用程序是一個(gè)包(Package),包中可能包含一個(gè)或者多個(gè)Android組件(component)。

提示:Android應(yīng)用程序包當(dāng)中也有一個(gè)應(yīng)用程序的概念,稱之為application。相比4種組件,這個(gè)概念在Android中對(duì)程序的運(yùn)行時(shí)影響不大。

Android應(yīng)用程序一般包含在一個(gè)單一的文件夾中,即每一個(gè)Android應(yīng)用程序是一個(gè)獨(dú)立的工程,包含了以下文件。

Android.mk:工程編譯文件,作用類似于Makefile,在SDK開發(fā)中不需要;

AndroidManifest.xml:工程描述文件,在其中定義了各種組件;

src目錄:Java源代碼,按照J(rèn)ava包的方式來(lái)組織目錄結(jié)構(gòu),包括各個(gè)Java類的源代碼;

res目錄:資源文件,包含XML文件、圖片、原始數(shù)據(jù)文件等,其中表示界面的布局(Layout)文件比較重要;

assets目錄:資產(chǎn)文件,將原樣復(fù)制到目標(biāo)的應(yīng)用程序包當(dāng)中。

1.3.2 Android應(yīng)用示例

SkeletonApp是Android中一個(gè)應(yīng)用程序的骨架,這個(gè)程序包含了兩個(gè)按鈕和菜單,兩個(gè)按鈕分別用于清除編輯文本框中的內(nèi)容,菜單的功能和兩個(gè)按鈕是相同的,菜單是Android中的標(biāo)準(zhǔn)UI元素。SkeletonApp程序的運(yùn)行結(jié)果如圖1-35所示。

圖1-35 SkeletonApp程序的運(yùn)行結(jié)果(左:?jiǎn)?dòng)界面;右:使用菜單)

1.源代碼工程結(jié)構(gòu)

SkeletonApp工程的源文件的結(jié)構(gòu)(沒有包含相對(duì)獨(dú)立的用于測(cè)試的代碼)按照目錄樹的方式如下所示:

        SkeletonApp/
        |-- Android.mk                         工程管理文件
        |-- AndroidManifest.xml                工程描述文件
        |-- res                                [資源文件目錄]
        |   |-- drawable
        |   |   `-- violet.jpg                     圖片文件
        |   |-- layout
        |   |   `-- skeleton_activity.xml            [布局文件目錄]
        |   `-- values
        |      |-- colors.xml                    顏色資源文件
        |      |-- strings.xml                    字符串資源文件
        |      `-- styles.xml                    樣式資源文件
        |-- src                                [Java源代碼目錄]
          `-- com
              `-- example
                  `-- android
                      `-- skeletonapp
                          `-- SkeletonActivity.java

Java源代碼SkeletonActivity.java中構(gòu)建了菜單、按鈕的動(dòng)作等功能,其中最核心部分如下所示:

        package com.example.android.skeletonapp;            // 定義應(yīng)用程序的包名
        public class SkeletonActivity extends Activity {
              // ......省略部分內(nèi)容
            @Override
            public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.skeleton_activity);  // 設(shè)置其中的布局文件
              // ......省略部分內(nèi)容
            }
        }

在SkeletonApp中,資源目錄res中的values目錄中除了strings.xml文件,還包含了colors.xml和styles.xml文件,這兩種文件也是Android中的標(biāo)準(zhǔn)資源文件。

colors.xml文件的內(nèi)容如下所示:

        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <!— 可以通過Resources.getColor()得到。-->
            <color name="red">#f00</color>
            <!--可以通過Resources.getDrawable()得到 -->
            <drawable name="semi_black">#80000000</drawable>
        </resources>

styles.xml文件用于定義程序中的不同樣式,其中的內(nèi)容如下所示:

        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <style name="ActionButton">
              <item name="android:layout_width">wrap_content</item>
              <item name="android:layout_height">wrap_content</item>
              <item name="android:textAppearance">
                              @style/TextAppearance.ActionButton</item>
            </style>
            <style name="TextAppearance" parent="android:TextAppearance">
            </style>
            <style name="TextAppearance.ActionButton">
              <item name="android:textStyle">italic</item>
            </style>
        </resources>

資源目錄res還包含了drawable目錄,表示可以繪制的內(nèi)容,這里的violet.jpg是一個(gè)JPEG格式的文件。

在res/layout目錄中的布局文件skeleton_activity.xml中的部分內(nèi)容引用了以上資源,內(nèi)容如下所示:

        <LinearLayout android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="center_horizontal"  android:orientation="horizontal"
            android:background="@drawable/semi_black">
            <Button android:id="@+id/back"   style="@style/ActionButton"
                    android:text="@string/back" />
            <ImageView android:id="@+id/image"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:paddingLeft="4dip"   android_paddingRight="4dip"
                      android:src="@drawable/violet" />
            <Button android:id="@+id/clear" style="@style/ActionButton"
                    android:text="@string/clear" android:textColor="@color/red" />
        </LinearLayout>

布局文件中引用了上面的資源,顏色可以作為字體的顏色,style/ActionButton作為按鈕的樣式,drawable/semi_black表示了背景的內(nèi)容,drawable/violet表示引用violet.jpg圖片作為圖像的內(nèi)容。例如根據(jù)上面styles.xml文件中的定義,兩個(gè)按鈕上的字體為斜體,第二個(gè)按鈕的字體顏色為紅色。

2.SDK環(huán)境中的編譯結(jié)構(gòu)

以上的SkeletonApp應(yīng)用程序包在SDK環(huán)境中經(jīng)過編譯之后將生成一些額外的文件。除去源代碼中已經(jīng)具有的文件以下,自動(dòng)生成的內(nèi)容的目錄結(jié)構(gòu)如下所示:

        SkeletonApp
        |-- bin                                     [目標(biāo)文件目錄]
        |   |-- classes.dex
        |   |-- com                                 [根據(jù)目錄生成字節(jié)碼]
        |   |   `-- example
        |   |      `-- android
        |   |          `-- skeletonapp
        |   |             |-- R$attr.class          [R*.class為資源對(duì)應(yīng)字節(jié)碼]
        |   |             |-- R.class
        |   |             |-- R$color.class
        |   |             |-- R$drawable.class
        |   |             |-- R$id.class
        |   |             |-- R$layout.class
        |   |             |-- R$string.class
        |   |             |-- R$style.class
        |   |             |-- SkeletonActivity$1.class    [主要Java源文件的字節(jié)碼]
        |   |             |-- SkeletonActivity$2.class
        |   |             `-- SkeletonActivity.class
        |   |-- resources.ap_
        |   `-- SkeletonApp.apk
        |-- default.properties                           [屬性文件]
        |-- gen                                           [自動(dòng)生成Java文件的目錄]
            `-- com
              `-- example
                  `-- android
                      `-- skeletonapp
                          `-- R.java

在SDK環(huán)境中,自動(dòng)生成的文件包括以下幾項(xiàng)內(nèi)容。

default.properties:工程的設(shè)置信息;

gen目錄:包含資源文件和AIDL文件生成的源代碼文件,其中資源文件生成的源代碼文件為R.java;

bin目錄:為根據(jù)類名生成的各個(gè)Java標(biāo)準(zhǔn)字節(jié)碼文件(*.class),classes.dex文件為經(jīng)過轉(zhuǎn)化的運(yùn)行于Android系統(tǒng)的特定字節(jié)碼。XXX.apk為最終生成的APK包,不同工程根據(jù)名字所生成的包名不同,例如SkeletonApp.apk。

3.APK包的結(jié)構(gòu)

Android中程序的編譯結(jié)構(gòu)基本類似,SkeletonApp工程生成的應(yīng)用程序包SkeletonApp.apk,本質(zhì)上是一個(gè)無(wú)壓縮率的ZIP包。經(jīng)過解壓縮后,可以看到其中包含了下面的一些內(nèi)容:

        SkeletonApp.apk/
        |-- AndroidManifest.xml              經(jīng)過aapt處理的工程描述文件
        |-- META-INF
        |   |-- CERT.RSA
        |   |-- CERT.SF
        |   `-- MANIFEST.MF
        |-- classes.dex                      Dalvik的字節(jié)碼文件
        |-- res
        |   |-- drawable
        |   |   `-- violet.jpg               保持原狀的圖片文件
        |   `-- layout
        |       `-- skeleton_activity.xml    經(jīng)過aapt處理的布局文件
        `-- resources.arsc

在這里drawable中的圖片文件保持原狀,layout中的布局文件經(jīng)過aapt處理成為壓縮的文本文件。

1.3.3 應(yīng)用程序生成運(yùn)行過程

1.應(yīng)用程序包生成的過程

在編譯Android應(yīng)用程序的過程中,Java源代碼使用Sun JDK將Java源程序編譯成Java字節(jié)碼文件(多個(gè)后綴名為.class的文件),這一步驟和標(biāo)準(zhǔn)的Java一致,然后通過Android自帶的工具軟件dex把所有的字節(jié)碼文件轉(zhuǎn)成DEX文件(單一文件classes.dex)。

AndroidManifest.xml文件經(jīng)過Android打包工具(aapt)處理后形成二進(jìn)制格式AndroidManifest.xml文件,實(shí)質(zhì)的內(nèi)容與以前相同。

各個(gè)資源文件也經(jīng)過aapt處理,其中布局等文本文件處理成二進(jìn)制文件,圖片等文件保持不變。

最后將這三個(gè)部分組合成一個(gè)應(yīng)用程序包(*.apk)。AndroidManifest.xml描述文件、Java源文件、資源文件是Android應(yīng)用程序的三個(gè)部分;在編譯之前的工程中是這三個(gè)部分,在編譯之后APK包依然是由這三個(gè)部分組成的。

Android應(yīng)用程序的編譯過程如圖1-36所示。

圖1-36 Android應(yīng)用程序的編譯過程

如圖1-36所示,Android源文件經(jīng)過了標(biāo)準(zhǔn)的Java編譯器的編譯,又經(jīng)過了dx工具的處理,標(biāo)準(zhǔn)的Java字節(jié)碼作為整個(gè)Android編譯的中間過程,最終生成的DEX文件(classes.dex)是一個(gè)單一文件,將工程中所有的Java源代碼文件對(duì)應(yīng)的字節(jié)碼集成在一起。資源文件和AndroidManifest.xml文件通過aapt工具進(jìn)行處理。

除此之外,assets目錄及所有內(nèi)容,將會(huì)原樣保存,放入到目標(biāo)APK包中,作為預(yù)編譯的內(nèi)容存在。在程序中,可以直接訪問其中的文件。

2.應(yīng)用程序包安裝運(yùn)行的過程

在運(yùn)行時(shí),APK包將首先進(jìn)行“安裝”,也就是將其中的DEX文件進(jìn)行優(yōu)化,優(yōu)化后的文件被保存到緩存區(qū)域,生成格式為DEY的優(yōu)化文件,然后Dalvik虛擬機(jī)將運(yùn)行這些DEY文件。如果應(yīng)用程序包文件不發(fā)生變化,DEY文件不會(huì)被重新生成;在應(yīng)用程序包發(fā)生更新的情況下,將重新由DEX生成DEY。

Android和標(biāo)準(zhǔn)Java的JAR包中字節(jié)碼的不同之處在于,標(biāo)準(zhǔn)Java每個(gè)源文件對(duì)應(yīng)字節(jié)碼文件一個(gè)Class文件,而Android將所有Java字節(jié)碼生成一個(gè)DEX文件。

主站蜘蛛池模板: 澄江县| 福建省| 定安县| 浙江省| 宁海县| 崇信县| 庄浪县| 清新县| 朝阳县| 阜康市| 赤壁市| 沙雅县| 邓州市| 卓尼县| 屯留县| 大安市| 金华市| 怀集县| 星子县| 汤原县| 彭山县| 酒泉市| 米脂县| 普安县| 安仁县| 永泰县| 全椒县| 嘉义县| 山阳县| 万盛区| 上高县| 连州市| 安图县| 保山市| 天门市| 山西省| 岚皋县| 平顶山市| 象山县| 额敏县| 通城县|