Android應用是使用Java編程語言編寫的。Android SDK工具把代碼、資源和數據文件編譯爲一個Android包,這是一個有.apk後綴的壓縮文件。一個單獨的.apk文件裏包含全部的代碼,這被看成一個應用,並且這個.apk文件是Android設備用來安裝應用的文件。html
一旦在設備上安裝了應用,那麼每一個應用都在自已安全的沙盒裏運行:java
1. Android操做系統是一個多用戶的Linux操做系統,在這個系統裏,每一個應用都是一個不一樣的用戶。android
2. 默認地,系統把每個應用都標識爲一個獨一無二的Linux用戶ID(這個ID僅僅能夠被系統所使用,對於應用程序來講,它是不可見的)。系統爲每一個應用的全部文件設置權限,所以,只有和應用用戶ID相匹配的應用才能夠讀取應用的文件。數據庫
3. 每一個進程都有自已的虛擬機(VM),所以,每一個應用的代碼都獨立地運行着。編程
4. 默認地,每一個應用都在它自已的Linux進程裏運行。當應用的任何一個組件須要被執行時,Android系統都會運行這個進程,而後徹底停下再也不須要的進程,或者恢復其它應用佔有的內存。安全
在這種方式中,Android系統實現了最小特權原則。也就是說,每一個應用默認都只能訪問它完成工做所必須的組件,不會訪問其它的。這樣作就建立了一個很是安全的環境,在這樣的環境裏,若是一個應用不給分配權限的話,它就不能訪問系統的任何內容。網絡
雖然如此,可是,對於一個程序,把數據共享給其它應用,或者從系統服務中獲取東東,有下面幾種方法:app
1. 可讓兩個應用共享同一個Linux 用戶ID,在這種狀況下,這兩個應用能夠獲取另一個的文件夾。爲了保護系統資源,有相同用戶ID的程序能夠運行在同一個Linux進程中,共享着相同的虛擬機(應用程序也應該有着一樣的證書籤名)框架
2. 應用程序也能夠經過請求權限的方式來獲取設備的數據,好比聯繫人信息,短信,存儲設備(SD card),照相機,藍牙,等等。全部應用程序的權限在安裝時候會展現給用戶,用戶贊成後才能安裝。異步
關於Android應用程序如何在系統中存在的基本知識,本文檔的其他部分向你介紹:
1. 定義了應用程序的核心框架組件。
2. 申明瞭應用程序用到的組件和所需的設備元素的mainfest文件。
3. 獨立於應用代碼的資源,可讓你的應用極大的優化它在各類配置設備的表現
應用組件
對於一個Android應用來講,應用組件是構建應用所必須的模塊。每個組件都是一個不一樣的點,系統能夠經過這些點進入你的應用。對於用戶來講,不是全部的組件都是真正的入口點,可是這些組件之間都有着相互的依賴性-每一個組件都是獨一無二的模塊,這些模塊有助於定義應用的總體行爲。
有四種不一樣類型的應用組件。每一種類型的組件都爲一個明確的意圖服務,也都有明確的生命週期,生命週期定義瞭如何建立和銷燬它。
下面就是應用組件的四種類型:
Activity
一個Activity表明了用戶界面的一個單獨的屏幕。例如,郵件相關的應用或許應該有一個Activity來展現新郵件的列表,另一個Activity來寫郵件,再一個Activity來讀取郵件。雖然在郵件應用中這些Activity一塊兒工做,造成了一個完整的用戶體驗,可是,每個部分又是獨立工做的。例如,另一個應用能夠啓動上面這些Activity中的任何一個Activity(若是郵件應用容許的話)。例如,照相應用能夠能夠啓動郵件應用裏的寫新郵件的應用,這樣作對用戶來講,就能夠分享照片了。
一個activity類就是一個實現了Activity 的Java類。在Activities開發者指導裏,你能夠獲取更多的知識。
服務
服務是運行在後臺,執行耗時較長的操做,或者甚至執行遠程進程的操做。服務不提供用戶界面。例如,當用戶來到其它應用時,服務會負責在後臺播放音樂,或者說,服務不會鎖住用戶和activity的交互,從網絡上獲取數據。好比一個activity,能夠啓動一個服務,並可讓它運行或者邦定到這個activity,以便與其進行交互操做。
一個服務是做爲Service子類來實現的,在Services開發指南中,你能學到更多關於它的使用。
Content providers - 內容提供
內容提供管理共享的應用數據集。你能夠把數據存儲在系統中,SQLite數據庫中,內頁中,或者其它任何你能夠從中獲取數據的本地持久性存儲。經過內容提供,其它的應用能夠查詢數據,甚至修改數據(若是內容提供容許的話)。例如,Android系統提供了管理用戶聯繫人數據的內容提供。這樣的話,任何具備合適權限的應用均可之內容提供(例如ContactsContract.Data)來對一個指定的聯繫人進行讀或寫的操做。
內容提供對於操做你應用中沒有共享的私有數據也是有用的。例如,Note Pad示例程序就使用了內容提供來保存筆記。
內容提供類是ContentProvider的子類,必須實現一系列標準的APIs,以讓其它的應用能執行交換操做。在Content Providers開發者指導中,你能夠學到更多的知識。
Broadcast receivers - 廣播接收器
廣播接收器是一個響應系統範圍廣播公告(通知)的組件。許多廣播信息都來源於系統,好比,通知屏幕關閉的廣播,系統電量低的廣播,或者是拍了一張照片的廣播。應用也能夠建立廣播,例如,在下載完某些數據時發送一條廣播,讓其它應用知道數據下載完成,可使用了。儘管廣播接收器不顯示一個用戶界面,可是廣播接收器能夠建立一個狀態欄通知,來通知用戶。但更多狀況下,一個廣播接收者只是一個其餘組件想要作極小量事件的一個"gateway」(途徑)。舉例,它可能發起一個服務,去執行關於某個事件的一些工做。
一個廣播接收者,是看成BroadcastReceiver子類被實現的。每一個廣播接收者都是從Intent對象衍生出來的。更多信息,請參考BroadcastReceiver。
Android系統設計的一個獨一無二的方面是任何應用能夠啓動另一個應用的組件。例如,若是你想讓用戶使用設備的照相機進行拍照操做,拍照功能頗有多是另一個應用的功能,可是你的應用須要使用它,那你就不須要再在你的應用中開發拍照的功能了。你只須要調用拍照應用來進行拍照就能夠了。拍照完成時,拍攝的照片會返回給你的應用,這樣,你就能夠對照片進行處理了。對於用戶來講,拍照功能好像就是你應用的功能同樣。
當系統調用一個組件時,系統會開啓組件所在應用的進程(這個應用可能沒有運行)而且實例化組件所需的類。例如,若是你的應用調用拍照程序拍照的功能,那麼系統就會啓動照相的進程,這個進程屬於拍照應用,不屬於你的應用。所以,和其它系統裏的應用不同,Android應用不只僅只有一個入口點(例如,沒有main()函數)。
由於系統的每個應用,在一個有文件權限的單獨的系統裏運行,所以,其它應用不能訪問,你的應用也不能直接激活其它應用的組件。雖然如此,可是,Android系統也能激活其它應用的組件,你必須給系統發送一個意圖來啓動一個指定的組件。而後,系統就會爲你啓動這個組件。
Activating components - 激活組件
四個組件類型中的三個:activity,service,broadcast receiver,是被叫作intent的異步消息激活的。在運行時,關於使用intent的更多信息,詳情請參見Intents and Intent Filters章節。把一個單獨的組件和其它組件相互綁定,而無論這個組件是否屬於你的應用(你能夠把它們想像爲一個消息,一個用於請求其它組件的動做)。
一個Intent由一個Intent對象建立,在intent裏,包含了一個激活組件的消息,這個組件要麼是一個指定的組件,要麼是指定類型的組件。能夠是顯式的,也能夠是隱式的。
對於activity和service來講,intent裏定義了執行的動做(例如,轉到一個視圖或是發送一些消息等),也可能定義了數據在哪一個URI上執行(這些中的一些,是組件啓動時就須要知道的)。例如,一個intent多是傳遞一個activity要瀏覽圖片或是打開網頁的請求。在某些狀況下,你能夠啓動一個activity來接收這個結果,在這種狀況下,activity會使用intent來返回結果(好比,你能夠指示一個intent,讓用戶取一我的的聯繫方式,並返回給你,返回的intent中會包含一個指向選定聯繫方式的URI)。
對於廣播接收器來講,intent僅僅只是定義了被廣播的公告的內容(設備電量低的廣播僅僅只是包含了一個已知的字符串「battery is low」)。
對於內容提供組件來講,它不會被intent激活,它會被內容解釋者(ContentResolver)所請求的目標所激活的。內容解釋者,處理全部與內容提供者的直接交換。因此組件不須要執行與提供者交換,而是調用ContentResolver對象方法。爲了安全起見,組件請求信息與內容提供者之間有一個抽象層。
下面是分別激活這幾種類型組件的方法:
1. 你能夠經過給startActivity()或startActivityForResult()(若是你想讓啓動的activity返回一個結果)方法傳遞intent參數來啓動一個activity(或是作一件新的事情)。
2. 你能夠經過給startService()方法傳遞一個intent來啓動一個service(或者給一個正在進行的service添加一些新的說明)。或者你能夠經過給bindService()方法傳遞一個intent參數來綁定到service上。
3. 你能夠經過給sendBroadcast()、sendOrderedBroadcast()、sendStickyBroadcast()方法傳遞一個intent來實例化一個廣播。
4. 你能夠經過在一個ContentResolver上調用query()方法來在一個內容提供上執行一個查詢。
關於使用intent的更多信息,詳情請參見Intents and Intent Filters章節。四種類型的組件也相應的提供了文檔:Activities、 Services、 BroadcastReceiver 、Content Providers。
Minfest文件
在Android系統啓動一個應用組件以前,系統必須經過讀取應用的AndroidMainfest.xml。在這個文件中,你必須申明你在應用中所使用的全部的組件,該文件必須位於項目文件的根目錄下。
爲了申明應用的組件,mainfest文件作了一系列的事情,例如:
1. 標識程序所需的任何的權限,例如訪問網絡的權限,讀取用戶聯繫人的權限。
2. 申明應用運行時須要的最小的API Level,應用會基於這個API運行的。
3. 使用應用用到的或是須要的軟硬件需求,例如照相機,藍牙,或多點觸摸屏。
4. 應用須要連接的API庫(而不是Android框架API),好比Google Maps library。
5. 其它。
申明組件
mainfest文件最基礎的任務就是通知系統應用有哪些組件。例如,mainfest能夠按照下面展現的方式來申明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屬性指定了用戶可見的標籤文本。
你必須使用下面的方式來申明應用的全部組件:
1. <activity> - activity組件
2. <service> - service組件
3. <receiver> - broadcast receiver組件
4. <provider> - content provider組件
在你項目中包含了,可是沒有在mainfest文件裏申明的activity、service和content provider組件,對於系統來講是不可見的,固然,也是不能用的。雖然如此,可是,broadcast receiver要麼在mainfest裏申明,要麼使用代碼動態生成(使用BroadcastReceiver),而後經過調用registerReceiver()方法在系統裏進行註冊,這都是能夠的。
關於如何爲應用構建mainfest的更多知識,請參見The AndroidManifest.xml File文檔。
申明組件功能
正如上面激活組件段落描述的那樣,你可使用一個intent來啓動activity、service和broadcast receiver。你也能夠在intent中顯式的指定目標組件(使用組件類名)。然而,intent真正的強大之處大於它的動做-即intent action。利用intent的動做,你只須簡單的描述你要執行的action類型(作爲可選操做,你能夠給添加執行動做相關的數據),而且容許系統在設備上找到一個組件,這樣就能夠執行那個動做並啓動它。若是有多個組件能夠執行intent指定的action,那麼用戶能夠選擇執行哪個。
系統指定響應intent組件的方式是經過比較設備上其它應用的mainfest文件裏提供的可接收的intent的過濾器後決定的。
當你在你應用的mainfest裏申明瞭一個組件時,做爲可選操做,你能夠包括intent filters(意圖過濾器)來指定組件的功能,這樣的話,該組件就能響應來自其它組件的intent。你能夠經過給申明組件的元素標籤裏添加<intent-filter>標籤來給你的組件申明一個/組意圖過濾器。
例如,包含寫郵件頁面的郵件應用或者會在mainfest裏申明一個意圖過濾器來響應發送的intent(爲了能"send"郵件)。而後在你的應用中可建立一個有"send"動做的intent(ACTION_SEND),當你使用startActivity()方法來執行intent時,系統會匹配到郵件應用裏的"send" activity並執行它。
關於使用intent的更多信息,詳情請參見Intents and Intent Filters章節。
申明應用的需求
有不少的Android設備,可是它們中不是全部都提供一樣的元素和能力。爲了阻止你的應用安裝在缺乏你應用所需元素的設備上,經過在你的manifest文件中聲明軟件硬件要求,明確的指出你的應用支持的硬件類型是很是重要的。大多數的申明只是信息的描述,系統也不會讀取它們,可是外部的設備,好比Google商店,會讀取它們,這樣作的目的是,當用戶在它們的設備上搜索應用時,能夠提供過濾。例如,若是你的應用須要照相機,並且使用的是從Android(API Level7)開始引入的APIs,那麼,你應該在你的mainfest文件裏申明這些需求。這樣作了,沒有照相機、或者低於2.1版本的設備就不能從Google商店裏安裝你的應用了。
然而,你也能夠申明你的應用使用了照相機,可是並不依賴於它。在這種狀況下,當設備沒有照相機而且照相功能被使用時,就須要你在應用運行時作檢查,並作提示。
當你在設計和開發應用時,你應該考慮一些重要的設備特性:
1. 屏幕尺寸和密度。
爲了經過屏幕類型來進行設備的分類,Android爲每一個設備定義了兩個特性:屏幕尺寸(屏幕的物理尺寸)和屏幕密度(在屏上的像素的物理密度,或者dpi--每英寸的點數)。爲了簡化屏幕配置的全部不一樣類型,Android系統把它們分紅可選的組,以便更容易定位。
屏幕大小:小,正常,大和極大
屏幕密度:低密度,中密度,高密度,和極高密度
默認狀況下,你的應用是兼容全部屏幕尺寸和密度的,由於Android系統對此作了適當的調整,以使得它適合你的UI佈局和圖像資源
然而,你應爲某個屏幕尺寸建立特殊的佈局,併爲某些密度提供特定的圖像,使用可選的資源,並在你的manifest文件中用<supports-screens> 元素聲明,以明確指出你的應用支持的屏幕尺寸.
更多信息,參考Supporting Multiple Screens文檔。
2. 輸入配置
許多設備爲用提供了一個不一樣類型輸入裝置,好比,硬件鍵盤,軌跡球,five-way導航pad.若是你的應用必需要一個特別的輸入硬件,那麼你應在你的應用中使用<uses-configuration>元素聲明.但時,應用必需要一個特別的輸入配置的狀況是極少的。
3. 設備特性
在一個裝有Android的設備中,有許多軟硬件特性,有可能有,或有可能沒有。好比照相機,光敏器件,藍牙,或某個版本的OpenGL,或者觸模屏的精度。你應該從不假設,在全部的裝有Android的設備中某個特色是可用的(除了標準的Android庫),因此你應該用 <uses-feature>元素聲明你的應用支持的特徵.
4. 平臺版本
不一樣的Android設備,常常運行不一樣的Android平臺版本,好比Android1.6或者2.3。每個成功的版本一般包括在前一個版本中不可用的API。爲了指出,那些APIs集是可用的,每一個平臺版本指定了一個API Level(好比, Android 1.0 is API Level 1 and Android 2.3 is API Level 9)。若是你使用的APIs是在1.0版以後,加入到平臺的,你應該用<uses-sdk>元素,聲明最小API級別,這樣就指出了那些API將被採用。
爲你的應用聲明全部必要性的要求很是重要。由於,當你把你的應用發佈到Android市場,市場將用這些聲明信息來過濾出,哪些應用在每一個設備是可用的。 一樣,你的應用應該只能在知足全部你應用需求的設備上纔可用。
更多關於Android市場如何基於這些需求過濾的,請看Filters on Google Play文檔
應用資源
一個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開發指南