- Android經典應用程序開發
- 韓超編著
- 679字
- 2019-01-09 15:18:42
1.3 Android應用程序的結構
1.3.1 Android應用程序的代碼組成
Android應用程序包含了工程文件、代碼和各種資源,主要由Java語言編寫,每一個應用程序將被編譯成Android的一個Java應用程序包(*.apk)。
一般情況下,Android應用程序由以下4種組件構成:
活動(Activity);
服務(Service);
廣播接收器(BroadcastReceiver);
內容提供者(ContentProvider)。
一個Android應用程序是一個包(Package),包中可能包含一個或者多個Android組件(component)。
提示:Android應用程序包當中也有一個應用程序的概念,稱之為application。相比4種組件,這個概念在Android中對程序的運行時影響不大。
Android應用程序一般包含在一個單一的文件夾中,即每一個Android應用程序是一個獨立的工程,包含了以下文件。
Android.mk:工程編譯文件,作用類似于Makefile,在SDK開發中不需要;
AndroidManifest.xml:工程描述文件,在其中定義了各種組件;
src目錄:Java源代碼,按照Java包的方式來組織目錄結構,包括各個Java類的源代碼;
res目錄:資源文件,包含XML文件、圖片、原始數據文件等,其中表示界面的布局(Layout)文件比較重要;
assets目錄:資產文件,將原樣復制到目標的應用程序包當中。
1.3.2 Android應用示例
SkeletonApp是Android中一個應用程序的骨架,這個程序包含了兩個按鈕和菜單,兩個按鈕分別用于清除編輯文本框中的內容,菜單的功能和兩個按鈕是相同的,菜單是Android中的標準UI元素。SkeletonApp程序的運行結果如圖1-35所示。

圖1-35 SkeletonApp程序的運行結果(左:啟動界面;右:使用菜單)
1.源代碼工程結構
SkeletonApp工程的源文件的結構(沒有包含相對獨立的用于測試的代碼)按照目錄樹的方式如下所示:
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中構建了菜單、按鈕的動作等功能,其中最核心部分如下所示:
package com.example.android.skeletonapp; // 定義應用程序的包名 public class SkeletonActivity extends Activity { // ......省略部分內容 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.skeleton_activity); // 設置其中的布局文件 // ......省略部分內容 } }
在SkeletonApp中,資源目錄res中的values目錄中除了strings.xml文件,還包含了colors.xml和styles.xml文件,這兩種文件也是Android中的標準資源文件。
colors.xml文件的內容如下所示:
<?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文件用于定義程序中的不同樣式,其中的內容如下所示:
<?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目錄,表示可以繪制的內容,這里的violet.jpg是一個JPEG格式的文件。
在res/layout目錄中的布局文件skeleton_activity.xml中的部分內容引用了以上資源,內容如下所示:
<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表示了背景的內容,drawable/violet表示引用violet.jpg圖片作為圖像的內容。例如根據上面styles.xml文件中的定義,兩個按鈕上的字體為斜體,第二個按鈕的字體顏色為紅色。
2.SDK環境中的編譯結構
以上的SkeletonApp應用程序包在SDK環境中經過編譯之后將生成一些額外的文件。除去源代碼中已經具有的文件以下,自動生成的內容的目錄結構如下所示:
SkeletonApp |-- bin [目標文件目錄] | |-- classes.dex | |-- com [根據目錄生成字節碼] | | `-- example | | `-- android | | `-- skeletonapp | | |-- R$attr.class [R*.class為資源對應字節碼] | | |-- R.class | | |-- R$color.class | | |-- R$drawable.class | | |-- R$id.class | | |-- R$layout.class | | |-- R$string.class | | |-- R$style.class | | |-- SkeletonActivity$1.class [主要Java源文件的字節碼] | | |-- SkeletonActivity$2.class | | `-- SkeletonActivity.class | |-- resources.ap_ | `-- SkeletonApp.apk |-- default.properties [屬性文件] |-- gen [自動生成Java文件的目錄] `-- com
`-- example `-- android `-- skeletonapp `-- R.java
在SDK環境中,自動生成的文件包括以下幾項內容。
default.properties:工程的設置信息;
gen目錄:包含資源文件和AIDL文件生成的源代碼文件,其中資源文件生成的源代碼文件為R.java;
bin目錄:為根據類名生成的各個Java標準字節碼文件(*.class),classes.dex文件為經過轉化的運行于Android系統的特定字節碼。XXX.apk為最終生成的APK包,不同工程根據名字所生成的包名不同,例如SkeletonApp.apk。
3.APK包的結構
Android中程序的編譯結構基本類似,SkeletonApp工程生成的應用程序包SkeletonApp.apk,本質上是一個無壓縮率的ZIP包。經過解壓縮后,可以看到其中包含了下面的一些內容:
SkeletonApp.apk/ |-- AndroidManifest.xml 經過aapt處理的工程描述文件 |-- META-INF | |-- CERT.RSA | |-- CERT.SF | `-- MANIFEST.MF |-- classes.dex Dalvik的字節碼文件 |-- res | |-- drawable | | `-- violet.jpg 保持原狀的圖片文件 | `-- layout | `-- skeleton_activity.xml 經過aapt處理的布局文件 `-- resources.arsc
在這里drawable中的圖片文件保持原狀,layout中的布局文件經過aapt處理成為壓縮的文本文件。
1.3.3 應用程序生成運行過程
1.應用程序包生成的過程
在編譯Android應用程序的過程中,Java源代碼使用Sun JDK將Java源程序編譯成Java字節碼文件(多個后綴名為.class的文件),這一步驟和標準的Java一致,然后通過Android自帶的工具軟件dex把所有的字節碼文件轉成DEX文件(單一文件classes.dex)。
AndroidManifest.xml文件經過Android打包工具(aapt)處理后形成二進制格式AndroidManifest.xml文件,實質的內容與以前相同。
各個資源文件也經過aapt處理,其中布局等文本文件處理成二進制文件,圖片等文件保持不變。
最后將這三個部分組合成一個應用程序包(*.apk)。AndroidManifest.xml描述文件、Java源文件、資源文件是Android應用程序的三個部分;在編譯之前的工程中是這三個部分,在編譯之后APK包依然是由這三個部分組成的。
Android應用程序的編譯過程如圖1-36所示。

圖1-36 Android應用程序的編譯過程
如圖1-36所示,Android源文件經過了標準的Java編譯器的編譯,又經過了dx工具的處理,標準的Java字節碼作為整個Android編譯的中間過程,最終生成的DEX文件(classes.dex)是一個單一文件,將工程中所有的Java源代碼文件對應的字節碼集成在一起。資源文件和AndroidManifest.xml文件通過aapt工具進行處理。
除此之外,assets目錄及所有內容,將會原樣保存,放入到目標APK包中,作為預編譯的內容存在。在程序中,可以直接訪問其中的文件。
2.應用程序包安裝運行的過程
在運行時,APK包將首先進行“安裝”,也就是將其中的DEX文件進行優化,優化后的文件被保存到緩存區域,生成格式為DEY的優化文件,然后Dalvik虛擬機將運行這些DEY文件。如果應用程序包文件不發生變化,DEY文件不會被重新生成;在應用程序包發生更新的情況下,將重新由DEX生成DEY。
Android和標準Java的JAR包中字節碼的不同之處在于,標準Java每個源文件對應字節碼文件一個Class文件,而Android將所有Java字節碼生成一個DEX文件。