標籤:des android style blog http color java 使用 io
原文在這裡:http://developer.android.com/guide/topics/manifest/manifest-intro.html
*Manifest譯作“清單”,這裡沿用英文便於理解,其它術語同理。
**文中連結都會跳轉到android開發人員網站。
App Manifest
每一個應用都必須在它的根目錄有一份AndroidManifest.xml檔案(必須使用這個名字)。Android系統必須在運行應用的任何代碼之前瞭解一些重要訊息,這些資訊就來自於這份manifest檔案。Manifest做的事情包括但不限於以下內容:
- 它提供了應用中的Java包的命名。包名是用於區別當前應用與其他應用的標識符。
- 它描述了應用中的所有組件 -組成應用的activity,service,broadcast receiver和content provider。同時它給實現這些組件的類命名,並公布了它們的作用範圍(比如它們可以處理什麼樣的intent)。這些聲明讓Android系統可以瞭解應用有哪些組件以及在什麼情況下可以啟動它們。
- 它決定了應用的組件是運行在哪一個進程中的。
- 它聲明了應用需要哪些許可權。許可權是用來訪問一些受保護的系統API,以及跟其他應用安全互動。
- 它也聲明了應用自己建立的許可權。其他應用如果要跟當前應用的組件互動,就需要在自己的manifest中聲明這些許可權。
- 它列出了應用的instrumentation類。這個類可以提供應用在運行時的profiling和其他資訊。只有在開發與測試階段才會需要列在manifest中,應用發布前記得移除。
- 它聲明了應用需要的最低Android API等級。
- 它列出了應用必須要連結到的一些庫。
*關於profiling和instrumentation我力不能及,果斷沿用英文,解釋看這裡:http://dbanotes.net/database/instrumentation_profiling.html
Manifest檔案的結構
顯示manifest檔案的一般結構和其中所有可以使用的元素。所有的元素,包括它的所有屬性,都單專屬一個完整的文檔。點擊圖中或者圖下方的元素列表,或者隨便哪個有連結的元素名稱,就可以看到對應元素的詳細資料。
<?xml version="1.0" encoding="utf-8"?><manifest> <uses-permission /> <permission /> <permission-tree /> <permission-group /> <instrumentation /> <uses-sdk /> <uses-configuration /> <uses-feature /> <supports-screens /> <compatible-screens /> <supports-gl-texture /> <application> <activity> <intent-filter> <action /> <category /> <data /> </intent-filter> <meta-data /> </activity> <activity-alias> <intent-filter> . . . </intent-filter> <meta-data /> </activity-alias> <service> <intent-filter> . . . </intent-filter> <meta-data/> </service> <receiver> <intent-filter> . . . </intent-filter> <meta-data /> </receiver> <provider> <grant-uri-permission /> <meta-data /> <path-permission /> </provider> <uses-library /> </application></manifest>
所有可以出現在manifest中的元素都列在下方了。只有它們是合法的元素,你不能添加你自己的元素或者屬性。
<action>
<activity>
<activity-alias>
<application>
<category>
<data>
<grant-uri-permission>
<instrumentation>
<intent-filter>
<manifest>
<meta-data>
<permission>
<permission-group>
<permission-tree>
<provider>
<receiver>
<service>
<supports-screens>
<uses-configuration>
<uses-feature>
<uses-library>
<uses-permission>
<uses-sdk>
慣例
Manifest中所有元素和屬性都應用到的一些慣例和規則。
元素
只有<manifest>和<application>元素是必須的,它們必須要呈現在manifest中且只能出現一次。其他大多數元素都可以出現很多次或者不出現——儘管為了讓你的manifest有意義,還是要有一些元素要寫進去的。
如果一個元素可以完全包含所有東西,那麼它會包含一些別的元素。所有的資料都是通過屬性設定的,而不是通過元素的character data (此處可能是xml的術語)。
同一級的元素一般是不排序的。舉例,<activity>, <provider>,和<service> 元素可以按任何順序混在一起。(activity-alias>元素是一個例外,它必須緊跟它想要化名的<activity>。)
屬性
正常來說,所有屬性都是隨意可選的。但是有一些屬性只能針對特定元素來使用以完成它的功能。請參考文檔作為指導。對於那些真的是隨意可選的,如果留空,那麼系統會分配一個預設值。
除了根節點的<manifest>元素中用到的某些屬性,所有的屬性都以android:當作首碼 - 舉例,android:alwaysRetainTaskState. 因為這個首碼是普遍通用的,所以文檔中提到屬性名稱的時候一般會省略它。
聲明類名
許多元素都對應著Java對象,包括代表應用本身的元素(<application>元素),和它的基本組件——<activity>, <service>, <receiver>, <provider>。
如果你定義了一個子類,當然大部分情況下你都會用到組件類的子類,這個子類需要通過name屬性來聲明。它的名稱必須包括了所屬包的包名。舉例,一個Service的子類應可以被定義成下面這樣:
<manifest . . . > <application . . . > <service android:name="com.example.project.SecretService" . . . > . . . </service> . . . </application></manifest>
然而,更簡便的方法是,如果字串的第一個字元是一個句號(註:英文句號,就是個點 -> "."),這個字元會自動用應用的包名擴充(定義在<manifest>元素的package屬性中)。下面的方式跟上面能達到一樣的賦值效果:
<manifest package="com.example.project" . . . > <application . . . > <service android:name=".SecretService" . . . > . . . </service> . . . </application></manifest>
當系統啟動一個組件,Android會建立這個命名過的子類的執行個體。如果沒有指定子類,系統會建立基類的執行個體。
多個值
當可以指定多個值的時候,請重複聲明多個元素,而不是在一個元素中列多個值。舉例,一個intent filter可以列多個action:
<intent-filter . . . > <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.INSERT" /> <action android:name="android.intent.action.DELETE" /> . . .</intent-filter>
資源資料
有些屬性擁有可以顯示給使用者的值 - 舉例,activity的標籤和表徵圖。這些屬性的值要從資源或者主題中分配並設定。資源的值請用以下的格式表述:
@[package:]type:name
當資源是跟應用在同一個包中,上句中的包名可以省略。type是指資源的類型,比如“string”或者“drawable” - name是可以標識指定資源的名稱,舉例:
<activity android:icon="@drawable/smallPic" . . . >
主題中的值用一個相似的方式表述,但是用一個"?"開頭,而不是"@":
?[package:]type:name
字串類型的值
當一個屬性的值是字串,必須使用雙反斜線(“\\”)來起始逸出字元。比如"\\n"用來換行,"\\uxxxx"表示一個Unicode字元。
特色功能
下面這個章節描述了一些Android特色功能是如何體現在manifest中的。
Intent過濾器
應用的核心組件(activity, service, broadcast receiver )都是通過intent呼叫起來的。intent是一個攜帶了“要做的動作”相關資訊的bundle (束?)- 包括將要處理的資料,將要執行這個動作的組件的分類,以及其他相關的指令。Android將分配一個合適的組件來響應這個intent,如果需要的話會啟動一個這個組件的執行個體,並將這個intent對象發送給它。
組件通過intent filter來廣播它的作用範圍,即它會響應哪些intent。由於Android系統必須要在一個組件被啟動之前知道它能處理哪些intent,就需要應用在manifest的<intent-filters>元素指定好intent filter。一個組件可以有任意數目的intent filter,每一個都描述一個不同的作用範圍。
一個明確指定組件類名的intent可以啟動對應的組件;過濾器在這裡面沒有發揮作用。但是一個沒有執行目標類名的intent,只能通過intent filter來啟動一個組件。
如果想瞭解intent filter如何篩選intent對象,請訪問單獨的文檔, Intents and Intent Filters。
表徵圖和標籤
相當數量的元素擁有icon和label屬性,即可以顯示一個小表徵圖和一個文字標籤給使用者。一些元素還擁有description屬性,即長篇的解釋性文字,也可以在螢幕上顯示出來。舉例,<permission>元素擁有這三種屬性,所以當使用者被問到是否允許某個應用申請許可權,使用者會看到表示許可權的表徵圖,許可權的名稱和許可權的詳細描述。
任何情況下,元素擁有的表徵圖和標籤都會成為它的子項目的預設表徵圖和標籤。這樣的話,<application>元素中的表徵圖和標籤就是它的所有組件的預設表徵圖和標籤。同樣的,一個組件的表徵圖和標籤也會成為它所有<intent-filter>的預設表徵圖和標籤,比如一個activity。如果<application>元素中設定了標籤,但是activity和它的intent filter沒有,那麼應用的標籤就會當作activity和intent filter的標籤。
intent filter的表徵圖和標籤是用在系統展示給使用者哪些組件可以用來完成某項功能(應用就是intent filter來向系統資料表明自己可以完成某項功能)的時候。舉例,一個帶著"android.intent.action.MAIN"和"android.intent.category.LAUNCHER"的filter可以向系統資料表明這個activity是應用的啟動activity,也就是應該顯示在launcher中的activity。這樣,這個filter的表徵圖和標籤就顯示在launcher中了。
許可權
Permission許可權是限制訪問裝置上的部分代碼或資料的約束條件。這個限制是為了保護重要的代碼和資料以防被誤用而破壞使用者體驗。
每個許可權都是用一個獨一無二的標籤來標識。一般標籤就會表明它要限制的行為。舉例,這裡有一些Android定義的許可權:
android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA
android.permission.SET_WALLPAPER
android.permission.DEVICE_POWER
一個特定功能至多會被一個許可權保護。
如果應用需要訪問被許可權保護的功能,它必須在manifest中用<uses-permission>元素來申請許可權。然後,當應用安裝到裝置上時,安裝器會通過檢查應用簽名的發行者,或者在一些情況下直接詢問使用者,來決定是否允許申請的許可權。讓許可權被允許時,應用可以使用受保護的功能。反之,它訪問受保護功能的動作會直接失敗並且不會通知使用者。
應用也可以用許可權來保護自己的組件。它可以採用任何Android定義的許可權,或其它應用定義的。甚至它可以定義自己的許可權。聲明一個新的許可權需要用到<permissions>元素。舉例,下面的activity就是這樣保護的:
<manifest . . . > <permission android:name="com.example.project.DEBIT_ACCT" . . . /> <uses-permission android:name="com.example.project.DEBIT_ACCT" /> . . . <application . . .> <activity android:name="com.example.project.FreneticActivity" android:permission="com.example.project.DEBIT_ACCT" . . . > . . . </activity> </application></manifest>
請注意,在這個例子中,DEBIT_ACCT的許可權不只是用<permission>元素宣告了,也用<uses-permission>元素申請了。應用中的其他組件必須在有這句申請之後才能啟動這個受保護的activity,即使這個保護是應用自己發起的。
同樣在這個例子中,如果permission屬性中的要填的是一個其他地方聲明過的許可權,比如android.permissionCALL_EMERGENCY_NUMBERS,就不需要再用<permission>元素宣告了,不過還是要是用<uses-permission>申請才行。
<permission-tree>元素宣告了一個許可權組定義在代碼中的的命名空間。<permission-group>為一個許可權的集合(包括在manifest中用<permission>聲明的許可權,以及定義在其它地方的許可權)定義了一個統一的標籤。它只會影響許可權按組呈現給使用者的結果。<permission-group>元素沒有指定哪一個許可權屬於這個組;它只是給了許可權組一個標籤。通過給<permission>元素的permission-group屬性賦值可以將許可權歸類到特定的組。
庫
每個應用都連結到預設的Android庫,這裡麵包括了基本的用於構建應用的包(比如一些常見的類 Activity, Service, View, Button, Application, ContentProvider等等)。
但是有些包依賴於它們自己的庫。當你的應用使用了這種包,它必須明確地請求連結到依賴的庫。Manifest中必須包含一個單獨的<uses-library>元素來指名每一個庫。(庫名可以在包的文檔中找到。)
翻譯Android API Guides: App Manifest