一篇就夠了系列之Android Manifest全解析

前言:

前面幾篇介紹了android四大組件的知識,可以發現,四大組件都必須在一個叫AndroidManifest.xml文件中進行註冊,那麼該文件的作用是什麼呢?你們的內容各有什麼意義呢?帶着這些疑問,來開始下面內容的學習。官方文檔,很詳細

作用:

  • 清單文件向 Android 系統提供應用的必要信息,系統必須具有這些信息方可運行應用的任何代碼
  • 爲應用的 Java 軟件包命名。軟件包名稱充當應用的唯一標識符
  • 描述應用的各個組件,包括構成應用的 Activity、服務、廣播接收器和內容提供程序。它還爲實現每個組件的類命名併發布其功能,例如它們可以處理的 Intent 消息。這些聲明向 Android 系統告知有關組件以及可以啓動這些組件的條件的信息
  • 確定託管應用組件的進程
  • 聲明應用必須具備哪些權限才能訪問 API 中受保護的部分並與其他應用交互。還聲明其他應用與該應用組件交互所需具備的權限
  • 列出 Instrumentation 類,這些類可在應用運行時提供分析和其他信息。這些聲明只會在應用處於開發階段時出現在清單中,在應用發佈之前將移除
  • 聲明應用所需的最低 Android API 級別
  • 列出應用必須鏈接到的庫

內容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.wenyi.interview">

    <permission
        android:name="interview.permission.MY_BROADCAST_PERMISSION"
        android:protectionLevel="normal"/>

    <uses-permission android:name="interview.permission.MY_BROADCAST_PERMISSION"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>

                <data android:scheme="myscheme"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".ScrollingActivity"
            android:label="@string/title_activity_scrolling"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="myscheme">
                </data>
            </intent-filter>
        </activity>

        <service android:name=".FourComponet.service.MyService"/>

        <activity android:name=".FourComponet.service.ServiceActivity">
        </activity>

        <service android:name=".FourComponet.service.MyIntentService"/>

        <activity android:name=".FourComponet.broadcast.BroadcastActivity">
        </activity>

        <receiver android:name=".FourComponet.broadcast.MyReceiver1">
            <intent-filter android:priority="-1000">
                <action android:name="com.wenyi.interview.mynormalb"/>
            </intent-filter>
        </receiver>
        <receiver android:name=".FourComponet.broadcast.MyReceiver2">
            <intent-filter android:priority="1000">
                <action android:name="com.wenyi.interview.mynormalb"/>
            </intent-filter>
        </receiver>

        <activity android:name=".FourComponet.contentProvider.ContentProviderActivity">
        </activity>

        <provider
            android:exported="true"
            android:enabled="true"
            android:authorities="com.wenyi.interview.provider"
            android:name=".FourComponet.contentProvider.MyContentProvider"/>
    </application>

</manifest>

可以發現,主要由以下幾個部分組成:

* 元素*

只有 和 元素是必需的,它們都必須存在並且只能出現一次。其他大部分元素可以出現多次或者根本不出現。但清單文件中必須至少存在其中某些元素纔有用。
如果一個元素包含某些內容,也就包含其他元素。所有值均通過屬性進行設置,而不是通過元素內的字符數據設置。

同一級別的元素通常不分先後順序。例如,、 和 元素可以按任何順序混合在一起。這條規則有兩個主要例外:

元素必須跟在別名所指的 之後。
元素必須是 元素內最後一個元素。換言之, 結束標記必須緊接在 結束標記後。

屬性

從某種意義上說,所有屬性都是可選的。但是,必須指定某些屬性,元素纔可實現其目的。請使用本文檔作爲參考。對於真正可選的屬性,它將指定默認值或聲明缺乏規範時將執行何種操作。
除了根 元素的一些屬性外,所有屬性名稱均以 android: 前綴開頭。例如,android:alwaysRetainTaskState。由於該前綴是通用的,因此在按名稱引用屬性時,本文檔通常會將其忽略。

聲明類名

許多元素對應於 Java 對象,包括應用本身的元素( 元素)及其主要組件:Activity ()、服務 ()、廣播接收器 () 以及內容提供程序 ()。

權限

uses-permission:用來申明需要的權限
permission:可以用來定義自己的權限,然後再進行申明

主要還是來看看四大組件:

Activity:

<activity android:allowEmbedded=["true" | "false"]
          android:allowTaskReparenting=["true" | "false"]
          android:alwaysRetainTaskState=["true" | "false"]
          android:autoRemoveFromRecents=["true" | "false"]
          android:banner="drawable resource"
          android:clearTaskOnLaunch=["true" | "false"]
          android:configChanges=["mcc", "mnc", "locale",
                                 "touchscreen", "keyboard", "keyboardHidden",
                                 "navigation", "screenLayout", "fontScale",
                                 "uiMode", "orientation", "screenSize",
                                 "smallestScreenSize"]
          android:documentLaunchMode=["intoExisting" | "always" |
                                  "none" | "never"]
          android:enabled=["true" | "false"]
          android:excludeFromRecents=["true" | "false"]
          android:exported=["true" | "false"]
          android:finishOnTaskLaunch=["true" | "false"]
          android:hardwareAccelerated=["true" | "false"]
          android:icon="drawable resource"
          android:label="string resource"
          android:launchMode=["standard" | "singleTop" |
                              "singleTask" | "singleInstance"]
          android:maxRecents="integer"
          android:multiprocess=["true" | "false"]
          android:name="string"
          android:noHistory=["true" | "false"]  
          android:parentActivityName="string" 
          android:permission="string"
          android:process="string"
          android:relinquishTaskIdentity=["true" | "false"]
          android:resizeableActivity=["true" | "false"]
          android:screenOrientation=["unspecified" | "behind" |
                                     "landscape" | "portrait" |
                                     "reverseLandscape" | "reversePortrait" |
                                     "sensorLandscape" | "sensorPortrait" |
                                     "userLandscape" | "userPortrait" |
                                     "sensor" | "fullSensor" | "nosensor" |
                                     "user" | "fullUser" | "locked"]
          android:stateNotNeeded=["true" | "false"]
          android:supportsPictureInPicture=["true" | "false"]
          android:taskAffinity="string"
          android:theme="resource or theme"
          android:uiOptions=["none" | "splitActionBarWhenNarrow"]
          android:windowSoftInputMode=["stateUnspecified",
                                       "stateUnchanged", "stateHidden",
                                       "stateAlwaysHidden", "stateVisible",
                                       "stateAlwaysVisible", "adjustUnspecified",
                                       "adjustResize", "adjustPan"] >   
    . . .
</activity>

包含它的文件:
<application>
可包含:
<intent-filter> 
<meta-data>

說明:

聲明一個實現應用的部分可視化用戶界面的 Activity(一個 Activity子類)。 所有 Activity 都必須由清單文件中的 元素表示。 任何未在該處聲明的 Activity 都將對系統不可見,並且也永遠不會被運行。

屬性:

*android:allowEmbedded*

表示該 Activity 可作爲另一 Activity 的嵌入式子項啓動。 它尤其適用於子項所在的容器(如 Display)爲另一 Activity 所擁有的情況。 例如,用於 Wear 自定義通知的 Activity 必須聲明此項,以便 Wear 在其上下文流中顯示 Activity,後者位於另一進程中。
該屬性的默認值爲 false。

*android:allowTaskReparenting*

當啓動 Activity 的任務接下來轉至前臺時,Activity 是否能從該任務轉移至與其有親和關係的任務 —“true”表示它可以轉移,“false”表示它仍須留在啓動它的任務處。
如果未設置該屬性,則對 Activity 應用由 <application> 元素的相應 allowTaskReparenting 屬性設置的值。 默認值爲“false”。

正常情況下,當 Activity 啓動時,會與啓動它的任務關聯,並在其整個生命週期中一直留在該任務處。您可以利用該屬性強制 Activity 在其當前任務不再顯示時將其父項更改爲與其有親和關係的任務。該屬性通常用於使應用的 Activity 轉移至與該應用關聯的主任務。

例如,如果電子郵件包含網頁鏈接,則點擊鏈接會調出可顯示網頁的 Activity。 該 Activity 由瀏覽器應用定義,但作爲電子郵件任務的一部分啓動。 如果將其父項更改爲瀏覽器任務,它會在瀏覽器下一次轉至前臺時顯示,當電子郵件任務再次轉至前臺時則會消失。

Activity 的親和關係由 taskAffinity 屬性定義。 任務的親和關係通過讀取其根 Activity 的親和關係來確定。因此,按照定義,根 Activity 始終位於具有相同親和關係的任務之中。 由於具有“singleTask”或“singleInstance”啓動模式的 Activity 只能位於任務的根,因此更改父項僅限於“standard”和“singleTop”模式。 (另請參閱 launchMode 屬性。)

android:alwaysRetainTaskState
系統是否始終保持 Activity 所在任務的狀態 —“true”表示保持,“false”表示允許系統在特定情況下將任務重置到其初始狀態。 默認值爲“false”。該屬性只對任務的根 Activity 有意義;對於所有其他 Activity,均忽略該屬性。
正常情況下,當用戶從主屏幕重新選擇某個任務時,系統會在特定情況下清除該任務(從根 Activity 之上的堆棧中移除所有 Activity)。 系統通常會在用戶一段時間(如 30 分鐘)內未訪問任務時執行此操作。

不過,如果該屬性的值是“true”,則無論用戶如何到達任務,將始終返回到最後狀態的任務。 例如,在網絡瀏覽器這類存在大量用戶不願失去的狀態(如多個打開的標籤)的應用中,該屬性會很有用。

*android:autoRemoveFromRecents*

由具有該屬性的 Activity 啓動的任務是否一直保留在概覽屏幕中,直至任務中的最後一個 Activity 完成爲止。 若爲 true,則自動從概覽屏幕中移除任務。 它會替換調用方使用的 FLAG_ACTIVITY_RETAIN_IN_RECENTS。 它必須是布爾值“true”或“false”。

*android:banner*

一種爲其關聯項提供擴展圖形化橫幅的可繪製資源。 將其與 <activity> 標記聯用可爲特定 Activity 提供默認橫幅,也可與 <application> 標記聯用,爲所有應用 Activity 提供橫幅。
系統使用橫幅在 Android TV 主屏幕中表示應用。 由於橫幅只顯示在主屏幕中,因此只應由包含的 Activity 能夠處理 CATEGORY_LEANBACK_LAUNCHER Intent 的應用指定。

必須將該屬性設置爲對包含圖像的可繪製資源的引用(例如 "@drawable/banner")。 沒有默認橫幅。

如需瞭解詳細信息,請參閱“面向電視的 UI 模式”設計指南中的橫幅,以及“電視應用入門指南”中的提供主屏幕橫幅。

*android:clearTaskOnLaunch*

是否每當從主屏幕重新啓動任務時都從中移除根 Activity 之外的所有 Activity —“true”表示始終將任務清除到只剩其根 Activity;“false”表示不做清除。 默認值爲“false”。該屬性只對啓動新任務的 Activity(根 Activity)有意義;對於任務中的所有其他 Activity,均忽略該屬性。
當值爲“true”時,每次用戶再次啓動任務時,無論用戶最後在任務中正在執行哪個 Activity,也無論用戶是使用返回還是主屏幕按鈕離開,都會將用戶轉至任務的根 Activity。 當值爲“false”時,可在某些情況下清除任務中的 Activity(請參閱 alwaysRetainTaskState 屬性),但並非一律可以。

例如,假定有人從主屏幕啓動了 Activity P,然後從那裏轉到 Activity Q。該用戶接着按了主屏幕按鈕,然後返回到 Activity P。正常情況下,用戶將看到 Activity Q,因爲那是其最後在 P 的任務中執行的 Activity。 不過,如果 P 將此標誌設置爲“true”,則當用戶按下主屏幕將任務轉入後臺時,其上的所有 Activity(在本例中爲 Q)都會被移除。 因此用戶返回任務時只會看到 P。

如果該屬性和 allowTaskReparenting 的值均爲“true”,則如上所述,任何可以更改父項的 Activity 都將轉移到與其有親和關係的任務;其餘 Activity 隨即被移除。

*android:configChanges*

列出 Activity 將自行處理的配置更改。在運行時發生配置更改時,默認情況下會關閉 Activity 然後將其重新啓動,但使用該屬性聲明配置將阻止 Activity 重新啓動。 Activity 反而會保持運行狀態,並且系統會調用其 onConfigurationChanged() 方法。
注:應避免使用該屬性,並且只應在萬不得已的情況下使用。 如需瞭解有關如何正確處理配置更改所致重新啓動的詳細信息,請閱讀處理運行時變更。

任何或所有下列字符串均是該屬性的有效值。多個值使用“|”分隔 — 例如,“locale|navigation|orientation”。

值   說明
“mcc”   IMSI 移動國家/地區代碼 (MCC) 發生了變化 - 檢測到了 SIM 並更新了 MCC。
“mnc”   IMSI 移動網絡代碼 (MNC) 發生了變化 - 檢測到了 SIM 並更新了 MNC。
“locale”    語言區域發生了變化 — 用戶爲文本選擇了新的顯示語言。
“touchscreen”   觸摸屏發生了變化。(這種情況通常永遠不會發生。)
“keyboard”  鍵盤類型發生了變化 — 例如,用戶插入了一個外置鍵盤。
“keyboardHidden”    鍵盤無障礙功能發生了變化 — 例如,用戶顯示了硬件鍵盤。
“navigation”    導航類型(軌跡球/方向鍵)發生了變化。(這種情況通常永遠不會發生。)
“screenLayout”  屏幕布局發生了變化 — 這可能是由激活了其他顯示方式所致。
“fontScale” 字體縮放係數發生了變化 — 用戶選擇了新的全局字號。
“uiMode”    用戶界面模式發生了變化 — 這可能是因用戶將設備放入桌面/車載基座或夜間模式發生變化所致。 請參閱 UiModeManager。 此項爲 API 級別 8 中新增配置。
“orientation”   屏幕方向發生了變化 — 用戶旋轉了設備。
注:如果您的應用面向 API 級別 13 或更高級別(按照 minSdkVersion 和 targetSdkVersion 屬性所聲明的級別),則還應聲明 "screenSize" 配置,因爲當設備在橫向與縱向之間切換時,該配置也會發生變化。

“screenSize”    當前可用屏幕尺寸發生了變化。它表示當前可用尺寸相對於當前縱橫比的變化,因此會在用戶在橫向與縱向之間切換時發生變化。 不過,如果您的應用面向 API 級別 12 或更低級別,則 Activity 始終會自行處理此配置變更(即便是在 Android 3.2 或更高版本的設備上運行,此配置變更也不會重新啓動 Activity)。
此項爲 API 級別 13 中新增配置。
“smallestScreenSize”    物理屏幕尺寸發生了變化。它表示與方向無關的尺寸變化,因此只有在實際物理屏幕尺寸發生變化(如切換到外部顯示器)時纔會變化。 對此配置的變更對應於smallestWidth 配置的變化。 不過,如果您的應用面向 API 級別 12 或更低級別,則 Activity 始終會自行處理此配置變更(即便是在 Android 3.2 或更高版本的設備上運行,此配置變更也不會重新啓動 Activity)。
此項爲 API 級別 13 中新增配置。
“layoutDirection”   佈局方向發生了變化。例如,從從左至右 (LTR) 更改爲從右至左 (RTL)。 此項爲 API 級別 17 中新增配置。
所有這些配置變更都可能影響應用看到的資源值。 因此,調用 onConfigurationChanged() 時,通常有必要再次獲取所有資源(包括視圖佈局、可繪製對象等),以正確處理變化。

*android:documentLaunchMode*

指定每次啓動任務時應如何向其中添加新的 Activity 實例。 該屬性允許用戶讓多個來自同一應用的文檔出現在概覽屏幕中。
該屬性有四個值,會在用戶使用該應用打開文檔時產生以下效果:

值   說明
“intoExisting”  Activity 會爲文檔重複使用現有任務。使用該值與不設置 FLAG_ACTIVITY_MULTIPLE_TASK 標誌、但設置 FLAG_ACTIVITY_NEW_DOCUMENT 標誌所產生的效果相同,如使用 Intent 標誌添加任務中所述。
“always”    Activity 爲文檔創建新任務,即便文檔已打開也是如此。 這與同時設置 FLAG_ACTIVITY_NEW_DOCUMENT 和 FLAG_ACTIVITY_MULTIPLE_TASK 標誌的效果相同。
“none”  該 Activity 不會爲 Activity 創建新任務。這是默認值,它只會在設置了 FLAG_ACTIVITY_NEW_TASK 時創建新任務。 概覽屏幕將按其默認方式對待此 Activity:爲應用顯示單個任務,該任務將從用戶上次調用的任意 Activity 開始繼續執行。
“never” 即使 Intent 包含 FLAG_ACTIVITY_NEW_DOCUMENT,該 Activity 也不會啓動到新文檔之中。 設置此值會替代 FLAG_ACTIVITY_NEW_DOCUMENT 和 FLAG_ACTIVITY_MULTIPLE_TASK 標誌的行爲(如果在 Activity 中設置了其中一個標誌),並且概覽屏幕將爲應用顯示單個任務,該任務將從用戶上次調用的任意 Activity 開始繼續執行。
注:對於除“none”和“never”以外的值,必須使用 launchMode="standard" 定義 Activity。 如果未指定此屬性,則使用 documentLaunchMode="none"。

*android:enabled*

系統是否可將 Activity 實例化 — "true" 表示可以,“false”表示不可以。 默認值爲“true”。
<application> 元素具有自己的 enabled 屬性,該屬性適用於所有應用組件,包括 Activity。 <application> 和 <activity> 屬性必須都是“true”(因爲它們都默認使用該值),系統才能將 Activity 實例化。 如果任何一個屬性是“false”,則無法進行實例化。

*android:excludeFromRecents*

是否應將該 Activity 啓動的任務排除在最近使用的應用列表(即概覽屏幕)之外。 也就是說,當該 Activity 是新任務的根 Activity 時,此屬性確定任務是否應出現在最近使用的應用列表中。 如果應將任務排除在列表之外,請設置“true”;如果應將其包括在內,則設置“false”。 默認值爲“false”。

*android:exported*

Activity 是否可由其他應用的組件啓動 —“true”表示可以,“false”表示不可以。若爲“false”,則 Activity 只能由同一應用的組件或使用同一用戶 ID 的不同應用啓動。
默認值取決於 Activity 是否包含 Intent 過濾器。沒有任何過濾器意味着 Activity 只能通過指定其確切的類名稱進行調用。 這意味着 Activity 專供應用內部使用(因爲其他應用不知曉其類名稱)。 因此,在這種情況下,默認值爲“false”。另一方面,至少存在一個過濾器意味着 Activity 專供外部使用,因此默認值爲“true”。

該屬性並非限制 Activity 對其他應用開放度的唯一手段。 您還可以利用權限來限制哪些外部實體可以調用 Activity(請參閱 permission 屬性)。

*android:finishOnTaskLaunch*

每當用戶再次啓動其任務(在主屏幕上選擇任務)時,是否應關閉(完成)現有 Activity 實例 —“true”表示應關閉,“false”表示不應關閉。 默認值爲“false”。
如果該屬性和 allowTaskReparenting 均爲“true”,則優先使用該屬性。 Activity 的親和關係會被忽略。 系統不是更改 Activity 的父項,而是將其銷燬。

*android:hardwareAccelerated*

是否應爲此 Activity 啓用硬件加速渲染 —“true”表示應啓用,“false”表示不應啓用。 默認值爲“false”。
從 Android 3.0 開始,爲應用提供了硬件加速 OpenGL 渲染器,以改善許多常見 2D 圖形運算的性能。 啓用硬件加速渲染器時,Canvas、Paint、Xfermode、ColorFilter、Shader 和 Camera 中的大多數運算都會得到加速。這可以提高動畫、滾動的流暢度和總體響應速度,即便是並不明確使用框架 OpenGL 庫的應用也會受益。 由於啓用硬件加速會增加資源消耗,因此您的應用將佔用更多內存。

請注意,並非所有 OpenGL 2D 運算都會得到加速。如果您啓用硬件加速渲染器,請對應用進行測試,以確保其在利用渲染器時不會出錯。

*android:icon*

一個表示 Activity 的圖標。該圖標會在需要在屏幕上表示 Activity 時顯示給用戶。 例如,代表啓動任務的 Activity 的圖標顯示在啓動器窗口中。該圖標通常附帶標籤(請參閱 android:label 屬性)。
必須將該屬性設置爲對包含圖像定義的可繪製資源的引用。 如果未設置該屬性,則改爲使用爲應用整體指定的圖標(請參閱 <application> 元素的 icon 屬性)。

這個 Activity 的圖標 — 無論設置於此處還是由 <application> 元素設置 — 同時也是 Activity 所有 Intent 過濾器的默認圖標(請參閱 <intent-filter> 元素的 icon 屬性)。

*android:label*

一種可由用戶讀取的 Activity 標籤。該標籤會在必須將 Activity 呈現給用戶時顯示在屏幕上。 它通常與 Activity 圖標一併顯示。
如果未設置該屬性,則改爲使用爲應用整體設置的標籤(請參閱 <application> 元素的 label 屬性)。

這個 Activity 的標籤 — 無論設置於此處還是由 <application> 元素設置 — 同時也是 Activity 所有 Intent 過濾器的默認標籤(請參閱 <intent-filter> 元素的 label 屬性)。

應將該標籤設置爲對字符串資源的引用,以便可以像用戶界面中的其他字符串那樣進行本地化。不過,爲便於您開發應用,也可將其設置爲原始字符串。

*android:launchMode*

有關應如何啓動 Activity 的指令。共有四種模式與 Intent 對象中的 Activity 標誌(FLAG_ACTIVITY_* 常量)協同工作,以確定在調用 Activity 處理 Intent 時應執行的操作。 這些模式是:
“standard” 
“singleTop” 
“singleTask” 
“singleInstance”

默認模式是“standard”。

如下表所示,這些模式分爲兩大類,“standard”和“singleTop”Activity 爲一類,“singleTask”和“singleInstance”爲另一類。使用“standard”或“singleTop”啓動模式的 Activity 可多次實例化。 實例可歸屬任何任務,並且可以位於 Activity 堆棧中的任何位置。 它們通常啓動到名爲 startActivity() 的任務之中(除非 Intent 對象包含 FLAG_ACTIVITY_NEW_TASK 指令,在此情況下會選擇其他任務 — 請參閱 taskAffinity 屬性)。

相比之下,“singleTask”和“singleInstance”Activity 只能啓動任務。 它們始終位於 Activity 堆棧的根位置。此外,設備一次只能保留一個 Activity 實例 — 只允許一個此類任務。

“standard”和“singleTop”模式只在一個方面有差異: 每次“standard”Activity 有新的 Intent 時,系統都會創建新的類實例來響應該 Intent。每個實例處理單個 Intent。同理,也可創建新的“singleTop”Activity 實例來處理新的 Intent。 不過,如果目標任務在其堆棧頂部已有一個 Activity 實例,那麼該實例將接收新 Intent(通過調用 onNewIntent());此時不會創建新實例。在其他情況下 — 例如,如果“singleTop”的一個現有實例雖在目標任務內,但未處於堆棧頂部,或者雖然位於堆棧頂部,但不在目標任務中 — 則系統會創建一個新實例並將其推送到堆棧上。

同理,如果您向上導航到當前堆棧上的某個 Activity,該行爲由父 Activity 的啓動模式決定。 如果父 Activity 有啓動模式 singleTop(或 up Intent 包含 FLAG_ACTIVITY_CLEAR_TOP),則系統會將該父項置於堆棧頂部,並保留其狀態。 導航 Intent 由父 Activity 的 onNewIntent() 方法接收。 如果父 Activity 有啓動模式 standard(並且 up Intent 不包含 FLAG_ACTIVITY_CLEAR_TOP),則系統會將當前 Activity 及其父項同時彈出堆棧,並創建一個新的父 Activity 實例來接收導航 Intent。

“singleTask”和“singleInstance”模式同樣只在一個方面有差異: “singleTask”Activity 允許其他 Activity 成爲其任務的組成部分。 它始終位於其任務的根位置,但其他 Activity(必然是“standard”和“singleTop”Activity)可以啓動到該任務中。 相反,“singleInstance”Activity 則不允許其他 Activity 成爲其任務的組成部分。它是任務中唯一的 Activity。 如果它啓動另一個 Activity,系統會將該 Activity 分配給其他任務 — 就好像 Intent 中包含 FLAG_ACTIVITY_NEW_TASK 一樣。

用例  啓動模式    多個實例?   註釋
大多數 Activity 的正常啓動  “standard”  是   默認值。系統始終會在目標任務中創建新的 Activity 實例並向其傳送 Intent。
“singleTop” 有條件 如果目標任務的頂部已存在一個 Activity 實例,則系統會通過調用該實例的 onNewIntent() 方法向其傳送 Intent,而不是創建新的 Activity 實例。
專用啓動
(不建議用作常規用途) “singleTask”    否   系統在新任務的根位置創建 Activity 並向其傳送 Intent。 不過,如果已存在一個 Activity 實例,則系統會通過調用該實例的 onNewIntent() 方法向其傳送 Intent,而不是創建新的 Activity 實例。
“singleInstance”    否   與“singleTask"”相同,只是系統不會將任何其他 Activity 啓動到包含實例的任務中。 該 Activity 始終是其任務唯一僅有的成員。
如上表所示,standard 是默認模式,並且適用於大多數的 Activity 類型。對許多類型的 Activity 而言,SingleTop 也是一個常見並且有用的啓動模式。 其他模式 — singleTask 和 singleInstance - 不適合 大多數應用因爲它們所形成的交互模式可能讓用戶感到陌生,並且與大多數其他應用迥異。

無論您選擇哪一種啓動模式,請務必在啓動期間以及使用返回按鈕從其他 Activity 和任務返回該 Activity 時對其進行易用性測試。

如需瞭解有關啓動模式及其與 Intent 標誌交互的詳細信息,請參閱任務和返回棧文檔。

*android:maxRecents*

概覽屏幕中位於此 Activity 根位置的任務數上限。 達到該條目數時,系統會從概覽屏幕中移除最近最少使用的實例。 有效值爲 1-50(低內存設備使用 25);0 爲無效值。 該值必須是整數,例如 50。默認值爲 16。

*android:multiprocess*

是否可以將 Activity 實例啓動到啓動該實例的組件進程內 —“true”表示可以,“false”表示不可以。默認值爲“false”。
正常情況下,新的 Activity 實例會啓動到定義它的應用進程內,因此所有 Activity 實例都在同一進程內運行。 不過,如果該標誌設置爲“true”,Activity 實例便可在多個進程內運行,這樣系統就能在任何使用實例的地方創建實例(前提是權限允許這樣做),但這幾乎毫無必要性或可取之處。

*android:name*

實現 Activity 的類的名稱,是 Activity 的子類。 該屬性值應爲完全限定類名稱(例如,“com.example.project.ExtracurricularActivity”)。不過,爲了簡便起見,如果名稱的第一個字符是句點(例如,“.ExtracurricularActivity”),則名稱將追加到 <manifest> 元素中指定的軟件包名稱。
應用一旦發佈,即不應更改該名稱(除非您設置了 android:exported="false")。

沒有默認值。必須指定該名稱。

*android:noHistory*

當用戶離開 Activity 並且其在屏幕上不再可見時,是否應從 Activity 堆棧中將其移除並完成(調用其 finish() 方法)—“true”表示應將其完成,“false”表示不應將其完成。 默認值爲“false”。
“true”一值表示 Activity 不會留下歷史軌跡。 它不會留在任務的 Activity 堆棧內,因此用戶將無法返回 Activity。 在此情況下,如果您啓動另一個 Activity 來獲取該 Activity 的結果,系統永遠不會調用 onActivityResult()。

該屬性是在 API 級別 3 引入的。

*android:parentActivityName*

Activity 邏輯父項的類名稱。此處的名稱必須與爲相應 <activity> 元素的 android:name 屬性指定的類名稱一致。
系統會讀取該屬性,以確定當用戶按下操作欄中的“向上”按鈕時應該啓動哪一個 Activity。 系統還可以利用這些信息通過 TaskStackBuilder 合成 Activity 的返回棧。

要支持 API 級別 4 - 16,您還可以使用爲 "android.support.PARENT_ACTIVITY" 指定值的 <meta-data> 元素來聲明父 Activity。例如:


如需瞭解有關聲明父 Activity 以支持向上導航的詳細信息,請閱讀提供向上導航。

該屬性是在 API 級別 16 引入的。

*android:permission*

客戶端啓動 Activity 或以其他方式令其響應 Intent 而必須具備的權限的名稱。 如果系統尚未向 startActivity() 或 startActivityForResult() 的調用方授予指定權限,其 Intent 將不會傳遞給 Activity。
如果未設置該屬性,則對 Activity 應用 <application> 元素的 permission 屬性設置的權限。 如果這兩個屬性均未設置,則 Activity 不受權限保護。

如需瞭解有關權限的詳細信息,請參閱簡介的權限一節和另一份文檔安全與權限。

*android:process*

應在其中運行 Activity 的進程的名稱。正常情況下,應用的所有組件都在爲應用創建的默認進程名稱內運行,您無需使用該屬性。 但在必要時,您可以使用該屬性替換默認進程名稱,以便讓應用組件散佈到多個進程中。
如果爲該屬性分配的名稱以冒號(“:”)開頭,則會在需要時創建應用專用的新進程,並且 Activity 會在該進程中運行。如果進程名稱以小寫字符開頭,Activity 將在該名稱的全局進程中運行,前提是它擁有相應的權限。這可以讓不同應用中的組件共享一個進程,從而減少資源佔用。

<application> 元素的 process 屬性可爲所有組件設置一個不同的默認進程名稱。

*android:relinquishTaskIdentity*

Activity 是否將其任務標識符交給任務棧中在其之上的 Activity。 如果任務根 Activity 的該屬性設置爲“true”,則任務會用其內的下一個 Activity 的 Intent 替換基本 Intent。 如果下一個 Activity 的該屬性也設置爲“true”,則該 Activity 會將基本 Intent 給予其在同一任務中啓動的任何 Activity。 系統繼續爲每個 Activity 執行此過程,直至遇到的某個 Activity 將該屬性設置爲“false”爲止。 默認值爲“false”。
如果該屬性設置爲“true”,則 Activity 還可利用 ActivityManager.TaskDescription 來更改概覽屏幕中的標籤、顏色和圖標。

*resizeableActivity*

指定應用是否支持多窗口顯示。您可以在 <activity> 或 <application> 元素中設置該屬性。

如果您將該屬性設置爲 true,則用戶可以分屏和自由形狀模式啓動 Activity。 如果您將該屬性設置爲 false,Activity 將不支持多窗口模式。 如果該值爲 false,且用戶嘗試在多窗口模式下啓動 Activity,該 Activity 將全屏顯示。

如果您的應用面向 API 級別 24 或更高級別,但未對該屬性指定值,則該屬性的值默認設爲 true。

該屬性是在 API 級別 24 添加的。

*android:screenOrientation*

Activity 在設備上的顯示方向。如果 Activity 是在多窗口模式下運行,系統會忽略該屬性。
其值可以是下列任一字符串:

“unspecified”   默認值。由系統選擇方向。在不同設備上,系統使用的政策以及基於政策在特定上下文所做的選擇可能有所差異。
“behind”    與 Activity 棧中緊接着它的 Activity 的方向相同。
“landscape” 橫向方向(顯示的寬度大於高度)。
“portrait”  縱向方向(顯示的高度大於寬度)。
“reverseLandscape”  與正常橫向方向相反的橫向方向。API 級別 9 中的新增配置。
“reversePortrait”   與正常縱向方向相反的縱向方向。API 級別 9 中的新增配置。
“sensorLandscape”   橫向方向,但根據設備傳感器,可以是正常或反向的橫向方向。API 級別 9 中的新增配置。
“sensorPortrait”    縱向方向,但根據設備傳感器,可以是正常或反向的縱向方向。API 級別 9 中的新增配置。
“userLandscape” 橫向方向,但根據設備傳感器和用戶的傳感器首選項,可以是正常或反向的橫向方向。 如果用戶鎖定了基於傳感器的旋轉,其行爲與 landscape 相同,否則,其行爲與 sensorLandscape 相同。API 級別 18 中的新增配置。
“userPortrait”  縱向方向,但根據設備傳感器和用戶的傳感器首選項,可以是正常或反向的縱向方向。 如果用戶鎖定了基於傳感器的旋轉,其行爲與 portrait 相同,否則,其行爲與 sensorPortrait 相同。API 級別 18 中的新增配置。
“sensor”    方向由設備方向傳感器決定。顯示方向取決於用戶如何手持設備,它會在用戶旋轉設備時發生變化。 但一些設備默認情況下不會旋轉到所有四種可能的方向。要允許全部四種方向,請使用 "fullSensor"。
“fullSensor”    方向由 4 種方向中任一方向的設備方向傳感器決定。這與 "sensor" 類似,不同的是它允許所有 4 種可能的屏幕方向,無論設備正常情況下采用什麼方向(例如,一些設備正常情況下不使用反向縱向或反向橫向,但它支持這些方向)。 API 級別 9 中的新增配置。
“nosensor”  決定方向時不考慮物理方向傳感器。傳感器會被忽略,因此顯示不會隨用戶對設備的移動而旋轉。 除了這個區別,系統在選擇方向時使用的政策與“unspecified”設置相同。
“user”  用戶當前的首選方向。
"fullUser"  如果用戶鎖定了基於傳感器的旋轉,其行爲與 user 相同,否則,其行爲與 fullSensor 相同,允許所有 4 種可能的屏幕方向。 API 級別 18 中的新增配置。
“locked”    將方向鎖定在其當前的任意旋轉方向。API 級別 18 中的新增配置。
注:如果您聲明其中一個橫向或縱向值,系統將其視爲對 Activity 運行方向的硬性要求。 因此,您聲明的值支持通過 Google Play 之類的服務進行過濾,這樣就能將您的應用只提供給支持 Activity 所要求方向的設備。 例如,如果您聲明瞭 "landscape""reverseLandscape""sensorLandscape",則您的應用將只提供給支持橫向方向的設備。 不過,您還應通過 <uses-feature> 元素明確聲明,您的應用要求採用縱向或橫向方向。 例如,<uses-feature android:name="android.hardware.screen.portrait"/>。這純粹是 Google Play(以及其他支持它的服務)提供的一種過濾行爲,平臺本身並不能控制當設備僅支持特定方向時您的應用能否安裝。

*android:stateNotNeeded*

能否在不保存 Activity 狀態的情況下將其終止併成功重新啓動 —“true”表示可在不考慮其之前狀態的情況下重新啓動,“false”表示需要之前狀態。 默認值爲“false”。
正常情況下,爲保存資源而暫時關閉 Activity 前,系統會調用其 onSaveInstanceState() 方法。 該方法將 Activity 的當前狀態存儲在一個 Bundle 對象中,然後在 Activity 重新啓動時將其傳遞給 onCreate()。 如果該屬性設置爲“true”,系統可能不會調用 onSaveInstanceState(),並且會向 onCreate() 傳遞 null 而不是 Bundle - 這與它在 Activity 首次啓動時完全一樣。

“true”設置可確保 Activity 能夠在未保留狀態時重新啓動。 例如,顯示主屏幕的 Activity 可以使用該設置來確保其由於某種原因崩潰時不會被移除。

*supportsPictureInPicture*

指定 Activity 是否支持畫中畫 顯示。如果 android:resizeableActivity 是 false,系統會忽略該屬性。

該屬性是在 API 級別 24 添加的。

*android:taskAffinity*

與 Activity 有着親和關係的任務。從概念上講,具有相同親和關係的 Activity 歸屬同一任務(從用戶的角度來看,則是歸屬同一“應用”)。 任務的親和關係由其根 Activity 的親和關係確定。
親和關係確定兩件事 - Activity 更改到的父項任務(請參閱 allowTaskReparenting 屬性)和通過 FLAG_ACTIVITY_NEW_TASK 標誌啓動 Activity 時將用來容納它的任務。

默認情況下,應用中的所有 Activity 都具有相同的親和關係。您可以設置該屬性來以不同方式組合它們,甚至可以將在不同應用中定義的 Activity 置於同一任務內。 要指定 Activity 與任何任務均無親和關係,請將其設置爲空字符串。

如果未設置該屬性,則 Activity 繼承爲應用設置的親和關係(請參閱 <application> 元素的 taskAffinity 屬性)。 應用默認親和關係的名稱是 <manifest> 元素設置的軟件包名稱。

*android:theme*

對定義 Activity 總體主題的樣式資源的引用。它會自動將 Activity 的上下文設置爲使用該主題(請參閱 setTheme()),它還可以引發 Activity 啓動前的“啓動”動畫(以更加符合 Activity 的實際外觀)。
如果未設置該屬性,則 Activity 繼承通過 <application> 元素的 theme 屬性爲應用整體設置的主題。 如果該屬性也未設置,則使用默認系統主題。如需瞭解詳細信息,請參閱樣式和主題開發者指南。

*android:uiOptions*

針對 Activity UI 的附加選項。
必須是下列值之一。

值   說明
"none"  無附加 UI 選項。這是默認值。
"splitActionBarWhenNarrow"  當水平空間受限時(例如在手持設備上的縱向模式下時)在屏幕底部添加一個欄以顯示應用欄(也稱爲操作欄)中的操作項)。 應用欄不是以少量操作項形式出現在屏幕頂部的應用欄中,而是分成了頂部導航區和底部操作項欄。 這可以確保操作項以及頂部的導航和標題元素都能獲得合理的空間。 菜單項不會拆分到兩個欄中,它們始終一起出現。
如需瞭解有關應用欄的詳細信息,請參閱添加應用欄培訓課。

該屬性是在 API 級別 14 添加的。

*android:windowSoftInputMode*

Activity 的主窗口與包含屏幕軟鍵盤的窗口的交互方式。 該屬性的設置影響兩個方面:
當 Activity 成爲用戶注意的焦點時軟鍵盤的狀態 — 隱藏還是可見。
對 Activity 主窗口所做的調整 — 是否將其尺寸調小以爲軟鍵盤騰出空間,或者當窗口部分被軟鍵盤遮擋時是否平移其內容以使當前焦點可見。
該設置必須是下表所列的值之一,或者是一個“state...”值加上一個“adjust...”值的組合。 在任一組中設置多個值(例如,多個“state...”值)都會產生未定義結果。各值之間使用垂直條 (|) 分隔。 例如:

<activity android:windowSoftInputMode="stateVisible|adjustResize" . . . >
此處設置的值(“stateUnspecified”和“adjustUnspecified”除外)替換主題中設置的值。

值   說明
"stateUnspecified"  不指定軟鍵盤的狀態(隱藏還是可見)。 將由系統選擇合適的狀態,或依賴主題中的設置。
這是對軟鍵盤行爲的默認設置。
“stateUnchanged”    當 Activity 轉至前臺時保留軟鍵盤最後所處的任何狀態,無論是可見還是隱藏。
“stateHidden”   當用戶選擇 Activity 時 — 也就是說,當用戶確實是向前導航到 Activity,而不是因離開另一 Activity 而返回時 — 隱藏軟鍵盤。
“stateAlwaysHidden” 當 Activity 的主窗口有輸入焦點時始終隱藏軟鍵盤。
“stateVisible”  在正常的適宜情況下(當用戶向前導航到 Activity 的主窗口時)顯示軟鍵盤。
“stateAlwaysVisible”    當用戶選擇 Activity 時 — 也就是說,當用戶確實是向前導航到 Activity,而不是因離開另一 Activity 而返回時 — 顯示軟鍵盤。
“adjustUnspecified” 不指定 Activity 的主窗口是否調整尺寸以爲軟鍵盤騰出空間,或者窗口內容是否進行平移以在屏幕上顯露當前焦點。 系統會根據窗口的內容是否存在任何可滾動其內容的佈局視圖來自動選擇其中一種模式。 如果存在這樣的視圖,窗口將進行尺寸調整,前提是可通過滾動在較小區域內看到窗口的所有內容。
這是對主窗口行爲的默認設置。
“adjustResize”  始終調整 Activity 主窗口的尺寸來爲屏幕上的軟鍵盤騰出空間。
“adjustPan” 不調整 Activity 主窗口的尺寸來爲軟鍵盤騰出空間, 而是自動平移窗口的內容,使當前焦點永遠不被鍵盤遮蓋,讓用戶始終都能看到其輸入的內容。 這通常不如尺寸調正可取,因爲用戶可能需要關閉軟鍵盤以到達被遮蓋的窗口部分或與這些部分進行交互。
該屬性是在 API 級別 3 引入的。

引入的版本:
API 級別 1,爲 noHistory 和 windowSoftInputMode 之外的所有屬性引入,這兩個屬性則是在 API 級別 3 中增加。

Service:

<service android:description="string resource"
         android:directBootAware=["true" | "false"]
         android:enabled=["true" | "false"]
         android:exported=["true" | "false"]
         android:icon="drawable resource"
         android:isolatedProcess=["true" | "false"]
         android:label="string resource"
         android:name="string"
         android:permission="string"
         android:process="string" >
    . . .
</service>

CONTAINED IN:
<application>
CAN CONTAIN:
<intent-filter> 
<meta-data>

receiver

<receiver android:directBootAware=["true" | "false"]
          android:enabled=["true" | "false"]
          android:exported=["true" | "false"]
          android:icon="drawable resource"
          android:label="string resource"
          android:name="string"
          android:permission="string"
          android:process="string" >
    . . .
</receiver>

CONTAINED IN:
<application>
CAN CONTAIN:
<intent-filter> 
<meta-data>

provider

<provider android:authorities="list"
          android:directBootAware=["true" | "false"]
          android:enabled=["true" | "false"]
          android:exported=["true" | "false"]
          android:grantUriPermissions=["true" | "false"]
          android:icon="drawable resource"
          android:initOrder="integer"
          android:label="string resource"
          android:multiprocess=["true" | "false"]
          android:name="string"
          android:permission="string"
          android:process="string"
          android:readPermission="string"
          android:syncable=["true" | "false"]
          android:writePermission="string" >
    . . .
</provider>

CONTAINED IN:
<application>
CAN CONTAIN:
<meta-data> 
<grant-uri-permission> 
<path-permission>

intent-filter
過濾器,跳轉依據

<intent-filter android:icon="drawable resource"
               android:label="string resource"
               android:priority="integer" >
               <action android:name="string" />
               <category android:name="string" />
               <data android:scheme="string"
              android:host="string"
              android:port="string"
              android:path="string"
              android:pathPattern="string"
              android:pathPrefix="string"
              android:mimeType="string" />

</intent-filter>

icon:顯示圖標
label:顯示名稱
priority:優先級
action:必須要與,可多個,Intent對象創建的時候需要action參數
category:類別,可選,可多個
data:URI等參數設置

meta-data
爲四大組件提供額外的值,可多個

<meta-data android:name="string"
           android:resource="resource specification"
           android:value="string" />

grant-uri-permission

<grant-uri-permission android:path="string"
                      android:pathPattern="string"
                      android:pathPrefix="string" />

path-permission

<path-permission android:path="string"
                 android:pathPrefix="string"
                 android:pathPattern="string"
                 android:permission="string"
                 android:readPermission="string"
                 android:writePermission="string" />

歡迎閱讀四大組件文章:

一篇就夠了系列之ContentProvider全解析

一篇就夠了系列之BroadcastReceiver全解析

一篇就夠了系列之Service全解析

一篇就夠了系列之Activity全解析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章