原文地址:http://developer.android.com/guide/components/fundamentals.html
學習目的:對Android應用程式有一個基本的認識,能夠快速的瞭解一個Android應用程式的構成部分,參照Training篇:Building
Your First App (這篇就不翻譯了),可以構建一個簡單的應用。
Android應用程式以java作為開發語言。用Android SDK 提供的工具,可以將應用程式所需要的資料和資源檔打包到一個android包檔案中,這個檔案用.apk作為副檔名。所有代碼都在單個.apk檔案中,當成一個應用。這個檔案就是通常安裝在Android裝置中的應用。
一旦安裝到了一個裝置,每個應用生存在它自己的安全沙箱中。
- 一個Android系統是一個多使用者的Linux系統,其中的每個應用都是一個不同的使用者。
- 預設情況下,系統給每個應用程式指派一個獨立的Linux使用者ID(這個ID只由系統使用並且對應用來說是不可知的),系統給在某個應用中的所有檔案設定了許可權,所以只有分配了那個使用者ID的應用才能訪問它們。
- 每個進程擁有它自己的虛擬機器,所以一個應用代碼的運行,與其他應用代碼的運行是隔離的。
- 預設情況下,每個應用程式均運行於它自己的Linux進程中。當應用程式中的任意代碼開始執行時,Android啟動一個進程,而當不再需要此進程或者其它應用程式又需要系統資源時,則關閉這個進程。
通過這種方法,Android系統實現了最小特權原則。預設,每個應用僅僅訪問需要工作的組件,並不多做其他的事。這樣建立了一個非常安全的環境,應用不能訪問系統沒有授權的其他部分。
然而,應用可以有多種方法來與其他應用,共用資料及訪問系統服務:
- 有可能安排兩個應用共用一個linux使用者ID,在那種情況下,它們能互相訪問相互的資料。為了節約系統資源,擁有相同使用者ID的應用,可能也被安排運行在同一個Linux進程中並共用相同的VM(應用必須被簽名成同樣的認證)。
- 所有應用能請求允許訪問硬體資料,比如像使用者通訊錄,SMS訊息及可掛載的存放裝置(SD card),網路攝影機,藍芽等,所有應用的許可權必須在使用者安裝時被許可。
上述了一個應用怎樣存在於一個系統中的相關基本概念,這個文檔的其他部分將向你介紹如下 內容:
- 定義在你的應用中核心架構組件
- 在manifest中,給你的應用,聲明組件及裝置特點請求
- 獨立於應用代碼的資源,可以讓你的應用極大的最佳化它在各種配置裝置的表現
Application Components-應用組件
應用組件是構建Android應用程式的關鍵和基石。每個組件是一個不同的入點,系統可以從這些點進入到你的應用。對於使用者來說,並不是每個組件都是實際的入點,但它們之間有一些依賴。但是每一個存在的組件都有它自己的一個入點,並扮演一個特定的角色——每一個都是獨一無二的構建塊,協助你定義你的應用的整體行為。
有四個不同類型的應用組件,每個類型服務於一個不同的目的,並有不同的生命週期,生命週期定義了如何建立和銷毀它。
下面是四種應用組件:
Activitys 活動
一個Activity代表螢幕上單獨的一個使用者介面。比如,一個email應用可能有一個Activity,這個Activity用於顯示新的email列表。而另一個Activity用於寫郵件,還有一個Activity用於讀取郵件。雖然這些Activities一起工作於email應用中,形成一個完整的使用者體驗但每一個部分又是相互獨立的。正因如此,其他的應用可以啟動這些activity中的任意一個(如果這個email應用允許的話)。比如,一個照相的應用,能開啟一個email應用中寫封新郵件的活動,讓使用者分享一張照片。
一個Activity需要繼承於 Activity 或者它的子類。你可以再Activities開發指南中瞭解到更多關於它的使用。
Services 服務
一個service是長期運行在後台,執行操作的組件,甚至可以為遠程進程工作。服務不提供使用者介面。比如,當使用者在其他應用中時,一個服務可能在背景播放音樂,或者在後台擷取資料,這並不影響使用者跟其他的活動進行互動操作。其他的組件,例如一個Activity可以啟動一個服務,並可以讓它運行或者綁定到這個Activity,一邊與其進行互動操作。
一個Service需要繼承與Service 或者它的子類,你可以再Services 開發指南中瞭解到更多關於它的使用。
Content providers 內容提供
一個content provider管理共用的應用資料集。你可以把資料存放區在檔案系統中、SQLite資料庫、網上、或你應用可以訪問的永久儲存空間中。通過內容提供者,其他的應用可以查詢甚至修改資料(如果內容提供者允許的話)。比如,Android系統提供一個內容提供者系統管理使用者通訊錄資訊。因此,任何擁用適當許可權的應用,可以查詢內容提供者的部分來(比如ContactsContract.Data)讀取和寫入關於某個人的資訊。內容提供者對於讀取和寫入屬於你的應用的私人的非共用資料也是非常有用的,比如Note
Pad範例應用程式,就使用內容提供者來儲存筆記的。
一個內容提供者被當作ContentProvider的子類實現,並且必須實現一套標準的APIs,以讓其他的應用能執行交換操作,參考Content
Providers 開發指南,以瞭解更多資訊。
Broadcast receivers 廣播接收者
廣播接收者是一個響應系統範圍廣播公告(通知)的組件.許多廣播資訊,都是來源於系統,比如,通知螢幕關閉的公告,電量低,或抓取了一張圖片.應用也能發起廣播,比如,讓其他的應用知道一些資料已下載到裝置了,並且他們可以使用了。雖然廣播接收者,不能顯示使用者介面,但當一個廣播事件發生時,它們可以建立一個狀態通知器,去提醒使用者.但更多情況下,一個廣播接收者只是一個其他組件,想要做極小量事件的一個"gateway”(途徑).舉例,它可能發起一個服務,去執行關於某個事件的一些工作。
一個廣播接收者,是當作BroadcastReceiver子類被實現的.每個廣播接收者都是從Intent對象衍生出來的。更多資訊,請參考BroadcastReceiver類
一個broadcast receiver是一個響應系統範圍廣播公告(通知)的組件。許多廣播資訊,都是來源於系統。比如,通知螢幕關閉的公告,電量低,或抓取了一張圖片。應用也能發起廣播比如,讓其他的應用知道一些資料已下載到裝置了,並且他們可以使用了。雖然廣播接收者不能顯示使用者介面,,但當一個廣播事件發生時,它們可以建立一個狀態通知器,去提醒使用者。但更多情況下,一個廣播接收者只是一個其他組件,想要做極小量事件的一個“gateway”(途徑)。舉例,它可能發起一個服務,去執行關於某個事件的一些工作。
一個廣播接受者是當作 BroadcastReceiver子類被實現的。每個廣播傳遞一個Intent對象。更多資訊,請參考BroadcastReceiver類。
任何一個應用能啟動另一個其他應用的組件,是Android系統設計獨一無二的方面(aspect)。比如,你想要用裝置的照相機拍一張圖片,其他的應用已經有了這個功能,你的應用就可以直接使用它,而不需要你自己去開發一個拍照相的activity。你並不需要合并(包含)或者甚至是連結camera應用中的代碼。而只是簡單的啟動camera應用中的activity就拍照。當拍照完成,可以把照片返回給你的應用,所以你能使用它。對於使用者來講,camera像是你應用中一部分。
當系統開啟一個組件時,它會啟動那個應用的進程(如果該應用沒有運行),並執行個體化該組件所需要的類。舉例,如果你的應用開啟一個camera應用的activity來拍照,這個activity將運行在屬於camera應用的進程中,而不是在你的應用的進程中。因此,不像大多數其他的系統的應用,Android應用沒有單個的入點(比如沒有main()函數)。
因為系統啟動並執行每個應用在一個帶有檔案許可權的獨立的進程中,這樣限制了對其他應用的訪問。你的應用不能直接存取其他應用中的組件。但時,Android系統也能啟用其他應用的組件,你必須傳一個訊息給系統,指定你想要啟動的組件,然後系統為你啟用這個組件。
Activating Components-啟用組件
4個組件中的其中三個組件——activities,serivces,和broadcast receivers----是被叫做intent的非同步訊息啟用的。在運行時,Intents把某個的組件與其他的組件互相綁定,而不管這個組件是否屬於你的應用還是其他的應用(你可以把它們想像成一個訊息,用於請求一個其他組件的動作)。
一個intent是一個由Intent建立的對象,該對象定義了一個啟用某個特定組件或者某個組件類型的訊息,一個intent可以是顯示的,同樣,也可以是隱式的。
對於activities和services,一個intent(意圖)定義了一個要執行的動作(比如:to”view”或"send" 些什麼),並指定了要採用的URI格式的資料(其中一些,是其他組件啟動所需要知道的)。比如,一個intent可能傳送一個請求給一個activity,要顯示一張圖片或開啟一個網頁。在有些情況,你啟動一個activity接收一個結果,這種情況下,activity將在Intent中返回一個結果。(比如,你可以指示一個intent,讓使用者取一個人的連絡方式,並返回給你,返回的intent中會包含一個指向選定連絡方式的URI)。
對於廣播接收者,intent只是定義了一個做為廣播的公告。(比如,一個廣播指出裝置電池低,它只是包含了一個動作字串,表示”電池低”)。
對於內容提供者,不會被intents所啟用。進一步講,它是內容解釋者(ContentResolver)所請求的目標所啟用的。contentresolver處理所有與內容提供者的直接交換,所以組件不需要執行與提供者交換,而是調用ContentResolver對象方法。為了安全起見,組件請求資訊與內容提供者之間有一個抽象層。
下面是啟用各種類型組件的幾個方法:
- 你可以通過傳一個
Intent給startActivity()
或 startActivityForResult()(當你想要activity返回一個參數),來啟動一個activity(或者要做一些新的事情)。
- 你可以傳一個
Intent給startService()方法,來啟動一個服務(或給一個新的指令給正在啟動並執行服啟)。或者你可以傳一個Intent給bindService()方法來綁定到服務。
- 你可以通過
sendBroadcast(),sendOrderedBroadcast(),或者sendStickyBroadcast()三種方法來廣播一個Intent。
- 你可以對ContentResolver調用query()方法,對
ContentResolver進行查詢。
關於使用intents的詳細資料,請看Intents andIntent Filters 文檔。在後面的文檔中,也有一些關於啟用某個組件的資訊Activities,Services,BroadcastReceiver
andContent Providers。
The Manifest File-資訊清單檔
在Android系統開啟一個應用組件之前,系統必須通過讀取AndroidManifest.xml檔案來知道組件的存在。你的應用必須把它所有的組件聲明在這個檔案中,並且必須在應用工程的根目錄下。
這個manifest檔案除了聲明組件外,還處理了許多其他的事情,比如:
- 指定應用請求的其他許可權,訪問網路或訪問使用者的通訊錄
- 聲明應用要求的最小API Level。應用使用的是哪個個API。
- 聲明應用請求和使用的軟硬體特徵,比如照相機,藍芽服務,或多點觸模屏
- 應用需要連結的API庫,比如Google Mapslibrary。
- 等等
Declaring components-聲明組件
manifest檔案的主要任務就是告訴系統這個應用程式有哪些組件。比如,manifest檔案聲明一個Activity:
<?xml version="1.0" encoding="utf-8"?><manifest ... > <application android:icon="@drawable/app_icon.png" ... > <activity android:name="com.example.project.ExampleActivity" android:label="@string/example_label" ... > </activity> ... </application></manifest>
在 <application>元素中 ,android:icon指定一個資源來作為應用程式的表徵圖。
在 <activity> 元素中,android:name 屬性用來指定一個Activity的全類名,android:label 屬性用來位Activity指定一個使用者可見的字串。
你必須通過下面的方式指定應用程式的所有組件:
<activity>
<service>
<receiver>
<provider>
Activities,services和 content providers 如果你寫在代碼中,而不聲明,那麼對系統來說是不可見的,也就是說,永遠都不會運行。然而broadcastreceivers 可以在manifest檔案中聲明,也可以在代碼中通過調用registerReceiver()方法動態註冊。
更多關於manifest檔案的結果,參考
The AndroidManifest.xml File 文檔。
Declaring component capabilities-聲明組件能力
在上面啟用組件的章節中,我們知道,可以通過Intent來開啟Activity,Service或者 Broadcast Receiver。你可以在Intent中顯示的指定目標組件(使用組件類名稱)然而,intent真正強大的是它的intent action(動作)。通過使用intent動作,你只須簡單的描述你要執行的action類型(並且,可選的與執行動作有關的資料)。如果有多個組件可以執行這個Intent描述的action,那麼使用者可以去選擇使用哪一個。
通過比較裝置上的應用的manifest檔案上的intent filters與接收到的intent.,系統確定那個組件可以響應一個intent。
當你在你的應用的manifest中聲明一個組件時,你可以可選擇包括intent filters(意圖過濾器),來指定組件的功能,以讓其能響應其他應用的intents。你可以為一個組件增加<intent-filter>子節點,為你組件聲明一個意圖過濾器。
比如,一個email應用中,建立email的一個activity可能在它的manifest 中聲明了一個意圖過濾器,以便能響應”send”意圖(為了發送郵件)。然後,在你的應用中的一個activity,建立了一個帶有”send” ACTION_SEND的意圖。當你調用startActivity()方法,啟動該意圖過濾器時,系統將其匹配到email應用的“send”活動,並運行它。
關於建立意圖過濾器的詳細資料,參考Intents and Intent Filters 文檔。
Declaring application requirements-聲明應用程式的需求
有許多裝置裝了Android,但它們並不提供所有相同的特點和功能.為了避免你的應用,裝在一個沒有你應用所必特徵的裝置上。通過在你的manifest檔案中聲明軟體硬體要求,明了的指出你的應用支援的硬體類型是非常重要的大多數聲明僅僅只是資訊,系統並不讀取他們,但像Android市場這樣的其他服務,將讀取它們,以便讓使用者在為他們的裝置尋找應用時,可以進行篩選。
比如,如果你的應用需要有照相機,並且使用的API是2.1(API Level 7),你應在你的manifest檔案中聲明這些要求。這樣,那些沒有照相機並且Android版本低於2.1的裝置,就不能從Android市場上安裝你的應用。
你也可以聲明你的應用使用camera,但不必須要求。那種情況,你的應用必在運行時一個檢查,以確定裝置是否有一個照相機,如果沒有照相機,並禁止與照相相關的功能。
下面是一些重要的裝置特性,你在設計和開發應用時必須要考慮的。
Screen size and density 螢幕尺寸與密度
為了能從它們的螢幕尺寸來分類裝置,Android為每個裝置定義了兩個特性:螢幕尺寸(螢幕的物理尺寸)和密度(在屏上的像素的物理密度,或者dpi--每英寸的點數)。為了簡化螢幕配置的所有不同類型,Android系統把它們分成可選的組,以便更容易定位。
螢幕大小:small, normal, large,and extra large。
螢幕密度:low density, medium density,high density, and extra high density。
預設情況下,你的應用是相容所有螢幕尺寸和密度的,因為Android系統對此做了適當的調整,以使得它適合你的UI布局和映像資源。然而,你應為某個螢幕尺寸建立特殊的布局,並為某些密度提供特定的映像。使用可選的資源,並在你的manifest檔案中用<supports-screens>元素宣告,以明確指出你的應用支援的螢幕尺寸。
更多資訊,參考
Supporting Multiple Screens。
Input configurations 輸入配置
許多裝置為用提供了一個不同類型輸入裝置,比如,硬體鍵盤,軌跡球,five-way導航pad.如果你的應用必須要一個特別的輸入硬體,那麼你應在你的應用中使用<uses-configuration>元素宣告。但時,應用必須要一個特別的輸入配置的情況是極少的。
Device features 裝置特性
在一個裝有Android的裝置中,有許多軟硬體特性,有可能有,或有可能沒有。比如照相機,光敏器件,藍芽,或某個版本的OpenGL,或者觸模屏的精度。你應該從不假設,在所有的裝有Android的裝置中某個特點是可用的(除了標準的Android庫),所以你應該用<uses-feature>元素宣告你的應用支援的特徵。
Platform Version 平台版本
不同的Android裝置,經常運行不同的Android平台版本,比如Android1.6或者2.3。每一個成功的版本通常包括在前一個版本中停用API。為了指出,那些APIs集是可用的,每個平台版本指定了一個API Level(比如, Android 1.0 是 API Level 1 ,Android 2.3
是 API Level 9)。API Level如果你使用的APIs是在1.0版之後加入到平台的,你應用聲明最小的API Level,這樣就指出了哪些API將被採用。
為你的應用聲明所有必要性的要求非常重要。因為,當你把你的應用發布到Android市場。市場將用這些聲明資訊來過濾出,那些應用在每個裝置是可用的。同樣,你的應用應該只能在滿足所有你應用需求的裝置上才可用。
更多關於Android市場如何基於這些需求過濾的,請看Filters on Google Play文檔。
Application Resources-應用程式資源
一個Android應用的組成不僅只是代碼----它還有與代碼獨立的資源,比像,音頻檔案,及與應用可顯映像任何其他相關的。比如,你應該定義動畫,菜單,風格,顏色,和用XML檔案定義活動的布局。使用應用資源,能讓你的應用在不修改任何代碼的情況下容易的升級各種特性---並且通過提供一套可選取的資源--能最佳化你的應用在各種配置不同的裝置中的表現(比如不同的語言和螢幕尺寸)。
對於每個包含在你的Android工程中的資源,SDK將其定義成一個唯一的整型ID,這樣你就可以在你的代碼中或在XML檔案中定義的其他資源中引用它。如果你的應用程式套件括一個圖片名字是logo.png(儲存在res/drawable/目錄 ),SDK工具將產生一個資源ID命名成R.drawable.logo,你可以用它來引用圖片,並插入你的使用者介面中.
提供與你的代碼分開的資源的一個很重要的方面是,使得你能為不同的配置的裝置提供可選資源。比如,在XML中定義UI字串,你可以把字串翻譯成各種不同的語言並儲存在不同的檔案中。然後,以基於語言限定詞,你可以追加資來源目錄名(比如res/values-fr/ 用文法語資源),和使用者語言設定,Android系會將相應的資源應用到你的UI中。
Android可選資源,支援許多不同的qualifiers (限定詞)。限定詞是一個包括在你的目錄名中的一個簡短的字串,是為了定義那些資源將用在,該配置的裝置上.再如,由於裝置的螢幕的方向和尺寸不同,你通常需要為你的活動定義不同的布局。比如,若裝置的螢幕是豎向(高),你可能要一個帶有重直button 的布局,當螢幕是橫向的(寬),按鈕應是水平對齊的。要根據方向來改變布局,你要定義兩個不同的布局,並在布局的目錄名中使用相應的限定詞(qualifier)。然後,系統將自動根據當前的裝置朝向來應用相應的布局。
要詳細瞭解你的應用中能包含的各種資源,及如何為各種配置的裝置建立可選資源,請看Application Resources開發指南。