- Android經(jīng)典應(yīng)用程序開發(fā)
- 韓超編著
- 1167字
- 2019-01-09 15:18:42
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文件。
- 一本書讀懂5G技術(shù)
- Altium DXP 2004電路設(shè)計(jì)
- 5G技術(shù)核心與增強(qiáng):從R15到R16
- 現(xiàn)代通信技術(shù)概論(第3版)
- 智慧城市:城市品質(zhì)新思維
- 機(jī)載激光雷達(dá)基礎(chǔ)原理與應(yīng)用
- Android 9編程通俗演義
- 電子工程師自學(xué)速成:設(shè)計(jì)篇(第2版)
- 拯救iphone之電路與故障檢修
- 高速設(shè)計(jì)技術(shù)
- 通信工程設(shè)計(jì)
- LTE教程:原理與實(shí)現(xiàn)(第3版)
- 光網(wǎng)絡(luò)信息傳輸技術(shù)
- 愛上單片機(jī)(第3版)
- 5G承載網(wǎng)絡(luò)運(yùn)維(高級(jí))