# 應用基礎
---
Android應用程序是用Java編程語言編寫的。Android SDK工具將您的代碼以及任何數據和資源文件編譯成APK,一個包含后綴的存檔文件的Android包.apk。一個APK文件包含Android應用程序的所有內容,是Android設備用于安裝該應用程序的文件。
每個Android應用程序都在自己的安全沙箱中,受到以下Android安全功能的保護:
* Android操作系統是一個多用戶Linux系統,其中每個應用程序是不同的用戶。
* 默認情況下,系統為每個應用程序分配一個唯一的Linux用戶ID(該ID僅由系統使用,對應用程序而言是未知的)。該系統為應用程序中的所有文件設置權限,以便只有分配給該應用程序的用戶標識才能訪問它們。
* 每個進程都有自己的虛擬機(VM),所以應用程序的代碼與其他應用程序隔離。
* 默認情況下,每個應用程序都在自己的Linux進程中運行。當任何應用程序的組件需要執行時,Android系統啟動該過程,然后在不再需要時關閉該進程,或者系統必須為其他應用程序恢復內存。
Android系統實現最低權限的原則。也就是說,默認情況下,每個應用程序只能訪問它所需的組件來完成其工作,而不再需要。這創建了一個非常安全的環境,其中應用程序無法訪問未向其授予權限的系統的部分。但是,有一些應用程序可以與其他應用程序和應用程序共享數據以訪問系統服務的方法:
* 可以安排兩個應用程序共享相同的Linux用戶ID,在這種情況下,他們可以訪問對方的文件。為了節省系統資源,具有相同用戶ID的應用程序也可以安排在同一個Linux進程中運行并共享同一個虛擬機。應用程序也必須使用相同的證書進行簽名。
* 應用程序可以請求訪問設備數據的權限,例如用戶的聯系人,SMS消息,可安裝存儲(SD卡),攝像頭和藍牙。用戶必須明確授予這些權限。有關詳細信息,請參閱 使用系統權限。
本文檔的其余部分介紹以下概念:
* 定義應用程序的核心框架組件。
* 您在其中聲明組件的清單文件以及應用程序所需的設備功能。
* 與應用程序代碼分離的資源,允許您的應用程序優化其各種設備配置的行為。
## 應用程序組件
應用程序組件是Android應用程序的基本構件。每個組件是系統或用戶可以通過該入口點輸入您的應用程序的入口點。一些組件依賴于其他組件。
有四種不同類型的應用程序組件:
* 活動
* 服務
* 內容提供商
* 廣播接收機
每種類型都具有不同的用途,并且具有明確的生命周期,定義組件的創建和銷毀。以下部分描述了四種類型的應用程序組件。
### 活動
一個活動是用于與用戶交互的入口點。它表示具有用戶界面的單個屏幕。例如,電子郵件應用可能有一個活動顯示新的電子郵件列表,另一個組成電子郵件的活動,以及另一個閱讀電子郵件的活動。雖然這些活動在一起形成了電子郵件應用程序中的一致性用戶體驗,但每個人都獨立于其他應用程序。因此,如果電子郵件應用程序允許,其他應用程序可以啟動任何一個這樣的活動。例如,相機應用程序可以在組成新郵件的電子郵件應用程序中啟動活動,以允許用戶共享圖片。一個活動有助于系統和應用之間的以下關鍵交互:
* 跟蹤用戶目前關心的內容(屏幕上是什么),以確保系統持續運行托管活動的進程。
* 知道以前使用的進程包含用戶可能返回(停止的活動)的內容,從而更加高度地保持這些進程的優先級。
* 幫助應用程序處理程序被殺死,以便用戶可以恢復到先前狀態的活動。
* 為應用程序提供一種方式來實現彼此之間的用戶流,并為系統協調這些流。(這里最經典的例子是分享)
您將一個活動作為Activity該類的子類實現。有關更多信息,Activity中 活動開發指南。
### 服務
一個服務是一個通用的入口點,用于保持應用在后臺運行的各種原因。它是在后臺運行以執行長時間運行的操作或為遠程進程執行工作的組件。服務不提供用戶界面。例如,當用戶處于不同的應用程序時,服務可能會在后臺播放音樂,或者可能通過網絡獲取數據而不會阻止用戶與活動的交互。另一個組件(如活動)可以啟動服務,讓它運行或綁定到它,以便與之進行交互。實際上有兩個非常明顯的語義服務告訴系統如何管理一個應用程序:已啟動的服務告訴系統保持運行,直到他們的工作完成。 這可能是即使在用戶離開應用程序后,也可以在后臺同步一些數據或播放音樂。在后臺同步數據或播放音樂也代表了兩種不同類型的啟動服務,它們修改系統如何處理它們:
* 音樂播放是用戶直接意識到的,所以應用程序告訴系統這是通過說它想成為前臺,通知告訴用戶它; 在這種情況下,系統知道應該盡量保持該服務的進程正常運行,因為用戶將不快樂。
* 常規后臺服務不是用戶直接意識到的運行,所以系統在管理進程方面有更大的自由。它可能允許它被殺死(然后稍后重新啟動服務),如果它需要RAM用于用戶更直接關心的事情。
綁定的服務運行是因為某些其他應用程序(或系統)已經表示要使用該服務。這基本上是為另一個進程提供API的服務。因此,系統知道這些進程之間存在依賴關系,因此如果進程A綁定到進程B中的一個服務,它就知道需要保持進程B(及其服務)運行A.另外,如果進程A是某事用戶關心,那么它也知道將進程B視為用戶關心的內容。由于其靈活性(更好或更差),服務已經成為各種上級系統概念的真正有用的基礎。動態壁紙,通知聽眾,屏幕保護程序,輸入法,無障礙服務,
一個服務被實現為一個子類Service。有關Service課程的更多信息,請參閱“ 服務開發人員指南”。
注意:如果您的應用定位到Android 5.0(API級別21)或更高版本,請使用JobScheduler該類來調度操作。JobScheduler具有通過優化調度作業來節省電池的優點,以降低功耗,并通過使用Doze API。有關使用此類的更多信息,請參閱JobScheduler 參考文檔。
### 廣播接收機
一個廣播接收器是使系統能夠提供事件給應用程序一個普通的用戶流量之外,使應用系統范圍的廣播通告響應的組件。由于廣播接收機是應用程序中的另一個明確定義的條目,所以系統甚至可以向當前運行的應用程序發送廣播。所以,例如,一個應用程序可以安排一個警報來發布通知,告訴用戶一個即將到來的事件...并且通過將該鬧鐘傳遞給該應用的BroadcastReceiver,沒有必要讓該應用保持運行,直到鬧鐘熄滅 許多廣播來源于系統 - 例如,廣播宣布屏幕已經關閉,電池電量不足或被捕獲。應用程序還可以啟動廣播 - 例如,讓其他應用程序知道某些數據已經下載到設備,并可供他們使用。雖然廣播接收機不顯示用戶界面,但是它們可以創建狀態欄通知 ,以在廣播事件發生時提醒用戶。然而,更常見的是,廣播接收機只是通往其他組件的網關,并且旨在進行非常少量的工作。例如,它可以JobService根據事件計劃執行一些工作 廣播接收機只是通往其他組件的網關,并且旨在進行非常少量的工作。例如,它可以根據事件計劃執行一些工作 廣播接收機只是通往其他組件的網關,并且旨在進行非常少量的工作。例如,它可以根據事件計劃執行一些工作JobScheduler
\
廣播接收機被實現為子類BroadcastReceiver ,每個廣播作為Intent對象傳送。有關更多信息,請參閱BroadcastReceiver課程。
內容提供商
一個內容提供商管理一組共享,你可以在文件系統中存儲,在SQLite數據庫,在網絡上,或者在您的應用程序可以訪問任何其他持久性存儲位置的應用程序的數據。通過內容提供商,如果內容提供商允許,其他應用程序可以查詢或修改數據。例如,Android系統提供管理用戶聯系信息的內容提供商。因此,具有適當權限的任何應用程序都可以查詢內容提供者,例如 ContactsContract.Data,讀取和寫入有關特定人員的信息。將內容提供者視為數據庫中的抽象是有誘惑力的,因為針對這種常見情況,內置提供程序存在大量的API和支持。然而,它們與系統設計的核心目的不同。對于系統, 內容提供商是用于發布由URI方案標識的命名數據項的應用程序的入口點。因此,應用程序可以決定如何將其包含的數據映射到URI命名空間,將這些URI發送給可以依次使用它們訪問數據的其他實體。系統在管理應用程序時可以使用一些特殊的操作:
分配URI不要求應用程序保持運行,所以URI可以在他們擁有的應用程序退出后持續存在。該系統只需要確保擁有的應用程序仍然在運行,當它必須從相應的URI檢索應用程序的數據。
這些URI還提供了一個重要的細粒度安全模型。例如,應用程序可以將剪貼板上具有的圖像的URI放置在其中,但將其內容提供商鎖定,以便其他應用程序不能自由訪問它。當第二個應用程序嘗試訪問剪貼板上的URI時,系統可以允許該應用通過臨時URI許可授權訪問數據, 以便允許其訪問該URI后面的數據,但第二個應用程序中沒有其他內容。
內容提供商也可以讀取和寫入您的應用程序私有的數據,而不是共享數據。例如,Note Pad示例應用程序使用內容提供商來保存筆記。
內容提供者實現為子類,ContentProvider 并且必須實現一組標準的API,以使其他應用程序能夠執行交易。有關更多信息,請參閱內容提供商開發人員指南。
Android系統設計的獨特之處在于,任何應用都可以啟動其他應用的組件。例如,如果您希望用戶使用設備攝像頭捕獲照片,則可能還有另一個應用程序可以使用該應用程序,而不是開發自己拍攝照片的活動。您不需要整合或甚至鏈接到相機應用程序的代碼。相反,您可以在拍攝照片的相機應用程序中簡單地啟動該活動。完成后,照片甚至可以返回到您的應用程序,以便您可以使用它。對于用戶來說,好像相機實際上是您的應用程序的一部分。
當系統啟動組件時,如果該應用程序尚未運行并實例化組件所需的類,那么它將啟動該應用程序的進程。例如,如果您的應用程序在相機應用程序中啟動捕獲照片的活動,該活動將在屬于相機應用程序的過程中運行,而不是在應用程序的進程中。因此,與大多數其他系統上的應用程序不同,Android應用程序不具有單個入口點(沒有main()功能)。
由于系統在單獨的進程中運行每個應用程序,而且具有限制訪問其他應用程序的文件權限,因此您的應用程序無法從其他應用程序直接激活組件。但是,Android系統可以。要激活另一個應用程序中的組件,請將指定您啟動特定組件的意圖的消息傳遞給系統。系統然后為您激活組件。
激活組件
四種組件類型中的三種 - 活動,服務和廣播接收器 - 被稱為意圖的異步消息激活。意圖在運行時將各個組件彼此綁定。您可以將它們視為要求其他組件執行操作的使者,無論該組件是屬于您的應用還是其他組件。
用一個Intent對象創建一個意圖,該對象定義一個消息來激活特定組件(顯式意圖)或特定類型的組件(隱含意圖)。
對于活動和服務,意圖定義要執行的操作(例如, 查看或 發送某些內容),并且可以指定要執行的數據的URI,以及啟動的組件可能需要知道的其他內容。例如,意圖可能傳達對活動的請求以顯示圖像或打開網頁。在某些情況下,您可以開始一個活動來接收結果,在這種情況下,活動也會將結果返回到其中Intent。例如,您可以發出意圖讓用戶選擇個人聯系人并將其返回給您。返回意圖包括指向所選聯系人的URI。
對于廣播接收機,意圖簡單地定義正在廣播的公告。例如,廣播,以指示該設備的電池為低僅包括一個公知的操作字符串,表示電池電壓低。
與活動,服務和廣播接收器不同,內容提供商不會通過意圖激活。相反,它們在被來自a的請求的目標時被激活ContentResolver。內容解析器處理與內容提供者的所有直接事務,以便與提供者執行事務的組件不需要而不是調用ContentResolver對象上的 方法。這在內容提供者和請求信息的組件(為了安全性)之間留下了一層抽象。
有單獨的方法激活每種類型的組件:
你可以開始一個活動或給它一些新的東西傳遞一個做Intent給startActivity()或startActivityForResult() (當你想活動返回的結果)。
使用Android 5.0(API級別21)及更高版本,您可以使用JobScheduler該類來調度操作。對于早期的Android版本,可以啟動服務(或提供新的指令來持續服務)通過傳遞Intent來startService()。你可以通過傳遞一個綁定到服務Intent到 bindService()。
你可以通過傳遞一個啟動的廣播Intent到方法,如 sendBroadcast(),sendOrderedBroadcast()或sendStickyBroadcast()。
你可以通過調用執行查詢到內容提供商query()上ContentResolver。
有關使用意圖的更多信息,請參閱意向和意圖過濾器文檔。以下文檔提供有關激活特定組件的更多信息: 活動, 服務 BroadcastReceiver和 內容提供商。
清單文件
之前Android系統可以啟動一個應用程序組件,系統必須知道該組件通過閱讀應用程序的存在清單文件,AndroidManifest.xml。您的應用必須在此文件中聲明其所有組件,該組件必須位于應用程序項目目錄的根目錄。
清單除了聲明應用程序的組件之外還會執行一些操作,如下所示:
標識應用程序所需的任何用戶權限,例如Internet訪問或對用戶聯系人的讀取權限。
聲明 應用程序所要求的最低 API級別,基于應用程序使用的API。
聲明應用程序使用或要求的硬件和軟件功能,如相機,藍牙服務或多點觸控屏幕。
聲明應用程序需要與(除Android框架API之外)(例如 Google Maps庫)進行鏈接的API 庫。
聲明組件
清單的主要任務是通知系統應用程序的組件。例如,清單文件可以聲明如下的活動:
<?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> 活動要素
<service> 服務元素。
<receiver> 廣播接收機的元素。
<provider> 內容提供商的元素。
在源中包含但不在清單中聲明的??活動,服務和內容提供者對于系統是不可見的,因此永遠不會運行。然而,廣播接收器可以在清單中聲明,也可以在代碼中動態地創建為 BroadcastReceiver對象,并通過調用向系統注冊 registerReceiver()。
有關如何構建應用程序的清單文件的更多信息,請參閱AndroidManifest.xml文件文件 。
聲明組件功能
如上所述,在激活組件中,您可以使用它 Intent來啟動活動,服務和廣播接收器。您可以在Intent intent 中使用明確命名目標組件(使用組件類名稱)。您還可以使用隱含意圖,其中描述要執行的操作的類型,以及可選的執行操作的數據。隱含意圖允許系統在設備上找到可以執行操作并啟動它的組件。如果有多個組件可以執行由意圖描述的動作,則用戶選擇要使用的組件。
注意:如果您使用意圖啟動 Service,請使用明確的 意圖確保您的應用程序安全 。使用隱含的意圖啟動服務是一個安全隱患,因為您無法確定什么服務將響應意圖,并且用戶無法查看哪個服務啟動。從Android 5.0(API級別21)開始,如果bindService() 使用隱式意圖調用,系統將拋出異常。不要為您的服務聲明意圖過濾器。
系統通過將接收到的意圖與設備上其他應用程序的清單文件中提供的意圖過濾器進行比較來識別可以對意圖做出響應的組件。
當您在應用程序的清單中聲明一個活動時,您可以選擇包含聲明活動功能的意圖過濾器,以便其可以響應其他應用程序的意圖。您可以通過將<intent-filter>組件的聲明元素的子元素添加為元素來為組件聲明一個意圖過濾器。
例如,如果您構建具有撰寫新電子郵件的活動的電子郵件應用程序,則可以聲明一個意圖過濾器以響應“發送”意圖(以便發送新電子郵件),如以下示例所示:
<manifest ... >
...
<application ... > <activity android:name = “com.example.project.ComposeEmailActivity” > <intent-filter> <action android:name = “android.intent.action.SEND “ /> <data android:type = ”* / *“ /> <category android:name = ”android.intent.category.DEFAULT“ /> </ intent-filter> </ activity> </ application> </ manifest >
如果另一個應用程序創建了一個意圖ACTION_SEND并將其傳遞給 startActivity(),系統可能會啟動您的活動,以便用戶可以起草并發送電子郵件。
有關創建意圖過濾器的更多信息,請參閱意向和意圖過濾器文檔。
聲明應用程式要求
有各種由Android提供的設備,并不是所有設備都具有相同的功能和功能。為防止您的應用程序安裝在缺少應用程序所需功能的設備上,請務必通過在清單文件中聲明設備和軟件要求來清楚地定義應用程序支持的設備類型的配置文件。大多數這些聲明僅供參考,系統不會閱讀它們,但是外部服務(如Google Play)會讀取它們,以便在用戶從設備搜索應用程序時提供過濾。
例如,如果您的應用程序需要相機并使用Android 2.1(API 7 級)中引入的API,則必須將它們聲明為清單文件中的要求,如以下示例所示:
<manifest ... > <uses-feature android:name = “android.hardware.camera.any” android:required = “true” /> <uses-sdk android:minSdkVersion = “7” android:targetSdkVersion = “19” /> ... </ manifest>
通過示例中顯示的聲明,沒有相機并且Android版本低于 2.1的設備無法從Google Play安裝您的應用。但是,您可以聲明您的應用程序使用相機,但 不需要。在這種情況下,您的應用程序必須設置required 屬性"false",并在運行時檢查設備是否有一個攝像頭,并禁用任何拍照功能為宜。
有關如何管理應用程序與不同設備的兼容性的更多信息,請參閱設備兼容性 文檔。
應用資源
Android應用程序不僅僅是代碼,它需要與源代碼分離的資源,例如圖像,音頻文件以及與應用程序可視化呈現相關的任何內容。例如,您可以使用XML文件定義動畫,菜單,樣式,顏色和活動用戶界面的布局。使用應用程序資源可以輕松更新應用程序的各種特性,而無需修改代碼。提供一組備用資源使您能夠針對各種設備配置(如不同的語言和屏幕尺寸)優化您的應用程序。
對于您在Android項目中包含的每個資源,SDK構建工具定義了一個唯一的整數ID,您可以使用它來從應用程序代碼或從XML定義的其他資源引用資源。例如,如果您的應用程序包含名為logo.png(保存在res/drawable/目錄中)的映像文件,則SDK工具將生成一個名稱的資源ID R.drawable.logo,可用于引用映像并將其插入到用戶界面中。
提供資源與您的源代碼分開的最重要的方面之一是能夠為不同的設備配置提供替代資源。例如,通過在XML中定義UI字符串,您可以將字符串轉換為其他語言,并將這些字符串保存在單獨的文件中。那么Android的應用相應的語言字符串基于語言的UI 預選賽 ,你追加到資源目錄的名稱(如res/values-fr/法國字符串值)和用戶的語言設置。
Android支持很多不同的預選賽為您替代資源。限定符是一個短字符串,您可以以資源目錄的名稱包含該字符串,以便定義應使用這些資源的設備配置。例如,您應該根據設備的屏幕方向和大小為您的活動創建不同的布局。當設備屏幕處于縱向(高)時,您可能希望具有垂直的按鈕布局,但是當屏幕處于橫向(寬)時,可以水平對齊按鈕。要根據方向更改布局,您可以定義兩個不同的布局,并將適當的限定符應用于每個布局的目錄名稱。然后,
有關您可以在應用程序中包含的各種資源的更多信息,以及如何為不同的設備配置創建替代資源,請閱讀“ 提供資源”。
- 簡介
- 第1章 Android 簡介(Introduction)
- 1.1.Application Fundamentals
- 1.2.Device Compatibility
- 1.3.System Permissions
- 1.3.1.Requesting Permissions
- 第2章 平臺架構(Platform Architecture)
- part2.1
- 第3章 應用組件(App Components)
- 第4章 應用資源(App Resources)
- 第5章 應用清單(App Manifest)
- 第6章 用戶界面(User Interface)
- 第7章 動畫和圖形(Animation and Graphics)
- 第8章 計算(Computation)
- 第9章 媒體應用(Media Apps)
- 第10章 媒體和相機(Media and Camera)
- 第11章 位置和傳感器(Location and Sensors)
- 第12章 連接(Connectivity)
- 第13章 文本和輸入(Text and Input)
- 第14章 數據存儲(Data Storage)
- 第15章 庫(Administration)
- 第16章 網絡應用(Web Apps)
- 第17章 最佳實踐(Best Practices)
- 總結
- 附錄 1 Android 系統的功能改變歷程