Android Manifest文件詳解
簡介
-
概述基本作用
-
文件結構
-
常見使用場景
概述
每個應用的根目錄中(一般是.../app/src/main/AndroidManifest.xml)都必須包含一個 AndroidManifest.xml 文件(且文件名精確無誤)。 Manifest文件為 Android 系統提供有關您的應用的基本信息,系統必須獲得這些信息才能運行任意應用代碼。 此外,Manifest文件還可執行以下操作:
-
為應用的 Java 軟件包命名。軟件包名稱充當應用的唯一標識符
-
描述應用的各個組件,即:構成應用的 Activity、服務(Service)、廣播接收器(BroadcastReceiver)和內容提供程序(ContentProvider)。 為實現每個組件的類命名并發布其功能(例如,它們可以處理的 Intent 消息)。根據這些聲明,Android 系統可以了解這組件具體是什么,以及在什么條件下可以啟動它們
-
確定將托管應用組件的進程
-
聲明應用必須具備哪些權限才能訪問 API 中受保護的部分并與其他應用交互
-
還聲明其他應用與該應用組件交互所需具備的權限
-
列出 Instrumentation 類,這些類可在應用運行期間提供分析和其他信息。這些聲明只會在應用處在開發和測試階段時出現在清單文件中;它們會在應用發布之前被刪除
-
聲明應用所需的最低 Android API 級別
-
列出應用必須鏈接到的庫
Manifest文件結構
下圖顯示了清單文件的通用結構及其可包含的每個元素。但是,并不是每個元素都是必須的。
Android Manifest Tag.png
共計元素23個,可出現在Manifest文件中的所有元素按字母順序羅列如下。 這些是僅有的合法元素;自己的元素或屬性無法添加在Manifest文件里。
常見的約定
有些約定和規則普遍適用于清單文件中的所有元素和屬性:
元素
只有 <manifest> 和 <application> 元素是必需的,它們都必須存在并且只能出現一次。其他大部分元素可以出現多次或者根本不出現,即便清單文件中必須至少存在其中某些元素才能完成任何有意義的操作也是如此。如果一個元素包含某些內容,也就包含其他元素。所有值均通過屬性進行設置,而不是通過元素內的字符數據設置。同一級別的元素通常不分先后順序。例如, <activity> 、 <provider> 和 <service> 元素可以按任何順序混合在一起。( <activity-alias> 元素不適用此規則: 它必須跟在別名所指的 <activity> 之后。)
屬性
從某種意義上說,所有屬性都是可選的。但是,有些屬性必須指定給元素以實現其目的。 請使用本文檔作為參考。 對于真正可選的屬性,它將指定默認值或聲明缺乏規范時將執行何種操作。除了根 <manifest> 元素的一些屬性外,所有屬性名稱均以 android:前綴開頭,例如,android:alwaysRetainTaskState。由于該前綴是通用的,因此在按名稱引用屬性時,本文檔通常會將其忽略。
聲明類名
許多元素對應于 Java 對象,其中包括應用本身的元素( <application> 元素)及其主要組件 — Activity ( <activity> )、服務 ( <service> )、廣播接收器 ( <receiver> ) 以及內容提供程序 ( <provider> )。如果按照您針對組件類( Activity 、 Service 、 BroadcastReceiver 和 ContentProvider )幾乎一直采用的方式來定義子類,則該子類需通過 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 過濾器可以列出多個操作:
<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 的標簽和圖標。 這些屬性的值應該本地化,因此需要通過資源或主題進行設置。 資源值用以下格式表示:
<p>@[ package :] type : name</p>舉個最常見的例子: <TextView android:textColor="@android:color/white" . . . >
其中,如果資源與應用位于同一軟件包中,則可忽略 package 名稱; type 是資源類型,如“字串符”或“圖片”; name 是標識特定資源的名稱。例如:
<activity android:icon="@drawable/smallPic" . . . >
主題中的值用類似的方法表示,但是以“?
”開頭而不是“@”: ?[ package :] type : name
字串符值
如果屬性值為字串符,則必須使用雙反斜杠(“\”) 轉義字符。例如,使用“\n”表示換行符或使用“\uxxxx”表示 Unicode 字符)。
文件功能
下文介紹如何在清單文件中利用某些 Android 特性。
Intent 過濾器
應用的核心組件(其 Activity、服務和廣播接收器)由 Intent 激活。Intent 是一系列用于描述所需操作的信息( Intent 對象),其中包括要執行操作的數據、應執行操作的組件類別以及其他相關說明。 Android 會找到合適的組件來響應 Intent,根據需要啟動組件的新實例,并將其傳遞到 Intent 對象。
組件將通過“Intent filter”公布其功能,即它們可響應的 Intent 類型。 由于 Android 系統在啟動某組件之前必須了解該組件可以處理哪些 Intent,因此 Intent 過濾器在清單文件中被指定為 <intent-filter> 元素。 一個組件可能有任意數量的過濾器,其中每個過濾器描述一種不同的功能。
顯式命名目標組件的 Intent 將激活該組件;過濾器不起作用。但是,不按名稱指定目標的 Intent 只有在能夠通過組件的一個過濾器時才可激活該組件。
有關如何根據 Intent 過濾器測試 Intent 對象的信息,請參閱單獨的文檔 Intent 和 Intent 過濾器 。
圖標和標簽
對于可以顯示給用戶的小圖標和文本標簽,大量元素具有 icon和 label屬性。此外,對于同樣可以顯示在屏幕上的較長說明文本,某些元素還具有 description屬性。例如, <permission> 元素具有所有這三個屬性。因此,當系統詢問用戶是否授權給請求獲得權限的應用時,權限圖標、權限名稱以及所需信息的說明均可呈現給用戶。
無論何種情況下,在包含元素中設置的圖標和標簽都將成為所有容器子元素的默認 icon和 label設置。因此,在 <application> 元素中設置的圖標和標簽是每個應用組件的默認圖標和標簽。 同樣,為組件(例如, <activity> 元素)設置的圖標和標簽是組件每個 <intent-filter> 元素的默認設置。 如果 <application> 元素設置標簽,但是 Activity 及其 Intent 過濾器不執行此操作,則應用標簽將被視為 Activity 和 Intent 過濾器的標簽。
在實現 Intent 過濾器公布的功能時,只要向用戶呈現組件,系統便會使用為過濾器設置的圖標和標簽表示該組件。 例如,具有“android.intent.action.MAIN”和“android.intent.category.LAUNCHER”設置的過濾器將 Activity 公布為可啟動應用的功能,即,公布為應顯示在應用啟動器中的功能。 因此,在過濾器中設置的圖標和標簽就是顯示在啟動器中的圖標和標簽。
權限
權限是一種限制,用于限制對部分代碼或設備上數據的訪問。 施加限制是為了保護可能被誤用以致破壞或損害用戶體驗的關鍵數據和代碼。
每種權限均由一個唯一的標簽標識。標簽通常指示受限制的操作。 例如,以下是由 Android 定義的一些權限:
android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA
android.permission.SET_WALLPAPER
android.permission.DEVICE_POWER
一個功能最多只能由一種權限保護。
如果應用需要訪問受權限保護的功能,則必須在清單文件中使用 <uses-permission> 元素聲明應用需要該權限。 但是,將應用安裝到設備上之后,安裝程序會通過檢查簽署應用證書的頒發機構并(在某些情況下)詢問用戶,確定是否授予請求的權限。 如果授予權限,則應用能夠使用受保護的功能。 否則,其訪問這些功能的嘗試將會失敗,并且不會向用戶發送任何通知。
此外,應用也可以使用權限保護自己的組件(Activity、服務、廣播接收器和內容提供程序)。它可以采用由 Android 定義(如 android.Manifest.permission 中所列)或由其他應用聲明的任何權限。或者,它也可以定義自己的權限。新權限用 <permission> 元素來聲明。 例如,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.permission.CALL_EMERGENCY_NUMBERS)聲明的權限,則無需使用 <permission> 元素再次聲明。 但是,仍有必要通過 <uses-permission> 請求使用它。
<permission-tree> 元素為一組將在代碼中定義的權限聲明命名空間。 同時, <permission-group> 為一組權限(包括在清單文件中使用 <permission> 元素聲明的權限以及在其他位置聲明的權限)定義標簽。它只影響如何對提供給用戶的權限進行分組。 <permission-group> 元素并不指定哪些權限屬于該組,而只是為組提供名稱。 通過向 <permission> 元素的 permissionGroup 屬性分配組名,將權限放入組中。
庫
每個應用均鏈接到默認的 Android 庫,該庫中包括構建應用(以及通用類,如 Activity、服務、 Intent 、視圖、按鈕、應用、ContentProvider 等)的基本軟件包。
但是,某些軟件包駐留在自己的庫中。如果應用使用來自其中任一軟件包的代碼,則必須明確要求其鏈接到這些軟件包。 清單文件必須包含單獨的 <uses-library> 元素來命名其中每個庫。(庫名稱可在軟件包的文檔中找到。)
來自:http://www.jianshu.com/p/543c5ff531a7