一、關於AndroidManifest.xml
AndroidManifest.xml清單文件是每個Android程序中必須的文件,它是整個Android程序的全局描述文件,除了能聲明程序中的Activities,Content Providers,Services,和Intent Receivers,還能指定應用的名稱、使用的圖標、包含的組件以及permissions和instrumentation(安全控制和測試)。
二、Hello World工程中的清單文件分析
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.wgh.helloworld"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" 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" /> </intent-filter> </activity> </application> </manifest>
各節點解釋(順序從上到下):
- xmlns:android:定義android命名空間,這樣使得Android中各種標准屬性能在文件中使用,提供了大部分元素中的數據。
- package:指定本應用內java主程序包的包名,它也是一個應用進程的默認名稱。
- application:一個AndroidManifest.xml中必須含有一個Application標簽,這個標簽聲明了每一個應用程序的組件及其屬性(如icon、label、permission等)。
- allowBackup:當allowBackup標志為true時,用戶即可通過adb backup和adb restore來進行對應用數據的備份和恢復,這可能會帶來一定的安全風險。
- icon:這個很簡單,就是聲明整個APP的圖標,圖片一般都放在drawable文件夾下。
- label:聲明整個APP的名字,字符串常量一般都放在values文件夾下的strings.xml里。
- supportsRtl:支持從右往左顯示的布局(正常布局在鏡子里面看到的左右對調過的樣子)。
- theme:是一個資源的風格,它定義了一個默認的主題風格給所有的activity,當然也可以在自己的theme里面去設置它,有點類似style。
- activity:定義APP中的一個組件Activity。
- name:該Activity的名字。
- intent-filter:廣播過濾器,后續會講到。
- <action android:name:指定程序入口Activity,在這里是MainActivity。
- <category android:name:指定當前動作(Action)被執行的環境。這里的CATEGORY_LAUNCHER決定應用程序是否顯示在程序列表里。
- 其余的:對應於各個開始節點的結束節點。
三、通用的清單文件結構以及各個節點的詳細介紹
通用清單文件結構:
<?xmlversion="1.0"encoding="utf-8"?> <manifest> <application> <activity> <intent-filter> <action/> <category/> </intent-filter> </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/> </provider> <uses-library/> </application> <uses-permission/> <permission/> <permission-tree/> <permission-group/> <instrumentation/> <uses-sdk/> <uses-configuration/> <uses-feature/> <supports-screens/> </manifest>
各個節點詳細解釋:
1、<Manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.woody.test" android:sharedUserId="string" android:sharedUserLabel="string resource" android:versionCode="integer" android:versionName="string" android:installLocation=["auto" | "internalOnly" | "preferExternal"] > </manifest>
-
xmlns:android
定義android命名空間,一般為http://schemas.android.com/apk/res/android,這樣使得Android中各種標准屬性能在文件中使用,提供了大部分元素中的數據。
-
package
指定本應用內java主程序包的包名,它也是一個應用進程的默認名稱。
-
sharedUserId
表明數據權限,因為默認情況下,Android給每個APK分配一個唯一的UserID,所以是默認禁止不同APK訪問共享數據的。若要共享數據,第一可以采用SharePreference方法,第二種就可以采用sharedUserId了,將不同APK的sharedUserId都設為一樣,則這些APK之間就可以互相共享數據了。
-
sharedUserLabel
一個共享的用戶名,它只有在設置了sharedUserId屬性的前提下才會有意義。
-
versionCode
是給設備程序識別版本(升級)用的,必須是一個interger值,代表app更新過多少次,比如第一版一般為1,之后若要更新版本就設置為2,3等等。
-
versionName
這個名稱是給用戶看的,你可以將你的APP版本號設置為1.1版,后續更新版本設置為1.2、2.0版本等等。
-
installLocation
安裝參數,是Android2.2中的一個新特性,installLocation有三個值可以選擇:internalOnly、auto、preferExternal
- 選擇preferExternal
系統會優先考慮將APK安裝到SD卡上(當然最終用戶可以選擇為內部ROM存儲上,如果SD存儲已滿,也會安裝到內部存儲上)。 - 選擇auto
系統將會根據存儲空間自己去適應。 - 選擇internalOnly
是指必須安裝到內部才能運行。
注:需要進行后台類監控的APP最好安裝在內部,而一些較大的游戲APP最好安裝在SD卡上。默認為安裝在內部,如果把APP安裝在SD卡上,首先得設置level為8,並且要配置android:installLocation這個參數的屬性為preferExternal
2、<Application>
<application android:allowClearUserData=["true" | "false"] android:allowTaskReparenting=["true" | "false"] android:backupAgent="string" android:debuggable=["true" | "false"] android:description="string resource" android:enabled=["true" | "false"] android:hasCode=["true" | "false"] android:icon="drawable resource" android:killAfterRestore=["true" | "false"] android:label="string resource" android:manageSpaceActivity="string" android:name="string" android:permission="string" android:persistent=["true" | "false"] android:process="string" android:restoreAnyVersion=["true" | "false"] android:taskAffinity="string" android:theme="resource or theme" > </application>
-
android:allowClearUserData('true' or 'false')
用戶是否能選擇自行清除數據,默認為true,程序管理器包含一個選擇允許用戶清除數據,當為true時,用戶可自己清理用戶數據,反之亦然。
-
android:allowTaskReparenting('true' or 'false')
是否允許activity更換從屬的任務,比如從短信息任務切換到瀏覽器任務。
-
android:backupAgent
這也是Android2.2中的一個新特性,設置該APP的備份,屬性值應該是一個完整的類名,如com.project.TestCase,此屬性並沒有默認值,並且類名必須得指定(就是個備份工具,將數據備份到雲端的操作)。
-
android:debuggable
這個從字面上就可以看出是什么作用的,當設置為true時,表明該APP在手機上可以被調試,默認為false,在false的情況下調試該APP,就會報以下錯誤:
Device XXX requires that applications explicitely declare themselves as debuggable in their manifest.
Application XXX does not have the attribute 'debuggable' set to TRUE in its manifest and cannot be debugged.
-
android:description / android:label
此兩個屬性都是為許可提供的,均為字符串資源,當用戶去看許可列表(android:label)或者某個許可的詳細信息(android:description)時,這些字符串資源就可以顯示給用戶。
label應當盡量簡短,只需要告知用戶該許可是在保護什么功能就行。而description可以用於具體描述獲取該許可的程序可以做哪些事情,實際上讓用戶可以知道如果他們同意程序獲取該權限的話,該程序可以做什么。我們通常用兩句話來描述許可,第一句描述該許可,第二句警告用戶如果批准該權限會可能有什么不好的事情發生。
-
android:enabled
Android系統是否能夠實例化該應用程序的組件,如果為true,每個組件的enabled屬性決定那個組件是否可以被 enabled;如果為false,它覆蓋組件指定的值,所有組件都是disabled。
-
android:hasCode('true' or 'false')
表示此APP是否包含任何的代碼,默認為true,若為false,則系統在運行組件時,不會去嘗試加載任何的APP代碼。一個應用程序自身不會含有任何的代碼,除非內置組件類。
比如Activity類,此類使用了AliasActivity類,當然這是個罕見的現象(在Android2.3可以用標准C來開發應用程序,可在androidManifest.xml中將此屬性設置為false,因為這個APP本身已經不含有任何的JAVA代碼了)
-
android:icon
這個很簡單,就是聲明整個APP的圖標,圖片一般都放在drawable文件夾下
-
android:killAfterRestore
這個屬性是指在一個完整的系統恢復操作之后應用程序是否被終止。單個應用程序的恢復操作不會引起應用程序的終止。完整的系統恢復操作一般僅在手機首次安裝時才會發生一次。第三方應用通常都不需要使用該屬性。該屬性的默認值為true,意為在完整的系統恢復期間,應用程序在結束處理其數據之后將被終止。
-
android:manageSpaceActivity
如果想自己管理數據目錄,則可以使用android:manageSpaceActivity屬性來控制,而不是默認的全部清除了/data/data/包名/里面的所有文件。當然我們還可以擴展,比如清除SD卡上的數據,如果擁有root權限,還可以用它當成垃圾清理。
-
android:name
為應用程序所實現的Application子類的全名。當應用程序進程開始時,該類在所有應用程序組件之前被實例化,若該類(比方androidMain類)是在聲明的package下,則可以直接聲明,但此類是在package下面的子包的話,就必須聲明為全路徑或android:name="package名稱.子包名.androidMain"。
-
android:permission
設置許可名,這個屬性若在<application>上定義的話,是一個給應用程序的所有組件設置許可的便捷方式,當然它是被各組件設置的許可名所覆蓋的。
-
android:presistent
該應用程序是否應該在任何時候都保持運行狀態,默認為false,因為應用程序通常不應該設置本標識,持續模式僅僅應該設置給某些系統應用程序才是有意義的。
-
android:process
應用程序運行的進程名,它的默認值為<manifest>元素里設置的包名,當然每個組件都可以通過設置該屬性來覆蓋默認值。如果你想兩個應用程序共用一個進程的話,你可以設置他們的android:process相同,但前提條件是他們共享一個用戶ID及被賦予了相同證書的時候。
-
android:restoreAnyVersion
同樣也是android2.2的一個新特性,用來表明應用是否准備嘗試恢復所有的備份,甚至該備份是比當前設備上要更新的版本,默認是false。
-
android:taskAffinity
擁有相同的affinity的Activity理論上屬於相同的Task,應用程序默認的affinity的名字是<manifest>元素中設定的package名。
-
android:theme
是一個資源的風格,它定義了一個默認的主題風格給所有的activity,當然也可以在自己的theme里面去設置它,有點類似style。
3、<Activity>
<activity android:allowTaskReparenting=["true" | "false"] android:alwaysRetainTaskState=["true" | "false"] android:clearTaskOnLaunch=["true" | "false"] android:configChanges=["mcc", "mnc", "locale", "touchscreen", "keyboard", "keyboardHidden", "navigation", "orientation", "screenLayout", "fontScale", "uiMode"] android:enabled=["true" | "false"] android:excludeFromRecents=["true" | "false"] android:exported=["true" | "false"] android:finishOnTaskLaunch=["true" | "false"] android:icon="drawable resource" android:label="string resource" android:launchMode=["multiple" | "singleTop" | "singleTask" | "singleInstance"] android:multiprocess=["true" | "false"] android:name="string" android:noHistory=["true" | "false"] android:permission="string" android:process="string" android:screenOrientation=["unspecified" | "user" | "behind" | "landscape" | "portrait" | "sensor" | "nosensor"] android:stateNotNeeded=["true" | "false"] android:taskAffinity="string" android:theme="resource or theme" android:windowSoftInputMode=["stateUnspecified", "stateUnchanged", "stateHidden", "stateAlwaysHidden", "stateVisible", "stateAlwaysVisible", "adjustUnspecified", "adjustResize", "adjustPan"] </activity>
-
android:alwaysRetainTaskState
是否保留狀態不變, 比如切換回home,再從新打開,activity處於最后的狀態。
比如一個瀏覽器擁有很多狀態(當打開了多個TAB的時候),用戶並不希望丟失這些狀態時,此時可將此屬性設置為true。
-
android:clearTaskOnLaunch
比如 P 是 Activity, Q 是被P 觸發的 Activity,然后返回Home, 重新啟動 P,是否顯示 Q。
-
android:configChanges
當配置list發生修改時, 是否調用 onConfigurationChanged() 方法。
比如 "locale | navigation | orientation",這個主要用來看手機方向改變的。 Android手機在旋轉后,layout會重新布局,如何做到呢?正常情況下, 如果手機旋轉了,當前Activity會被殺掉,然后根據方向重新加載這個Activity,就會從onCreate開始重新加載;如果你設置了這個選項,當手機旋轉后,當前Activity之后會調用onConfigurationChanged() 方法而不跑onCreate()方法等。
-
android:excludeFromRecents
是否可被顯示在最近打開的activity列表里,默認是false。
-
android:finishOnTaskLaunch
當用戶重新啟動這個任務的時候,是否關閉已打開的activity,默認是false。
如果這個屬性和allowTaskReparenting都是true,那么這個屬性就是王牌,Activity的親和力將被忽略,該Activity已經被摧毀並非re-parented。
-
android:launchMode
在多Activity開發中,有可能是自己應用之間的Activity跳轉,或者夾帶其他應用的可復用Activity。可能會希望跳轉到原來某個Activity實例,而不是產生大量重復的Activity。這需要為Activity配置特定的加載模式,而不是使用默認的加載模式。
-
android:multiprocess
是否允許多進程,默認是false。
-
android:noHistory
當用戶從Activity上離開並且它在屏幕上不再可見時,Activity是否從Activity stack中清除並結束,默認是false,Activity不會留下歷史痕跡。
-
android:screenOrientation
activity顯示的模式,默認為unspecified:由系統自動判斷顯示方向。
landscape:橫屏模式,寬度比高度大;
portrait:豎屏模式, 高度比寬度大;
user模式:用戶當前首選的方向;
behind模式:和該Activity下面的那個Activity的方向一致(在Activity堆棧中的);
sensor模式:有物理的感應器來決定;
nosensor模式:忽略物理感應器,這樣就不會隨着用戶旋轉設備而更改了。
-
android:stateNotNeeded
Activity被銷毀或者成功重啟時是否保存狀態。
-
android:windowSoftInputMode
Activity主窗口與軟鍵盤的交互模式,可以用來避免輸入法面板遮擋問題,Android1.5后的一個新特性。
這個屬性能影響兩件事情:
1.當有焦點產生時,軟鍵盤是隱藏還是顯示
2.是否減少活動主窗口大小以便騰出空間放軟鍵盤
各值的含義:
- stateUnspecified:軟鍵盤的狀態並沒有指定,系統將選擇一個合適的狀態或依賴於主題的設置
- stateUnchanged:當這個activity出現時,軟鍵盤將一直保持在上一個activity里的狀態,無論是隱藏還是顯示
- stateHidden:用戶選擇activity時,軟鍵盤總是被隱藏
- stateAlwaysHidden:當該Activity主窗口獲取焦點時,軟鍵盤也總是被隱藏的
- stateVisible:軟鍵盤通常是可見的
- stateAlwaysVisible:用戶選擇activity時,軟鍵盤總是顯示的狀態
- adjustUnspecified:默認設置,通常由系統自行決定是隱藏還是顯示
- adjustResize:該Activity總是調整屏幕的大小以便留出軟鍵盤的空間
- adjustPan:當前窗口的內容將自動移動以便當前焦點從不被鍵盤覆蓋和用戶能總是看到輸入內容的部分
4、<intent-filter>
<intent-filter android:icon="drawable resource" android:label="string resource" android:priority="integer" > <action /> <category /> <data /> </intent-filter>
-
priority屬性
有序廣播主要是按照聲明的優先級別,如A的級別高於B,那么,廣播先傳給A再傳給B。優先級別就是用設置priority屬性來確定,范圍是從-1000~1000,數越大優先級別越高。
Intent filter內會設定的資料包括action、data與category三種,也就是說filter只會與intent里的這三種資料作對比動作。
-
action屬性
action很簡單,只有android:name這個屬性。常見的android:name值為android.intent.action.MAIN,表明此activity是作為應用程序的入口。
-
category屬性
category也只有android:name屬性。常見的android:name值為android.intent.category.LAUNCHER(決定應用程序是否顯示在程序列表里,優先級最高的組件)
-
data屬性
<data android:host="string" android:mimeType="string" android:path="string" android:pathPattern="string" android:pathPrefix="string" android:port="string" android:scheme="string" />
- 每個<data>元素指定一個URI和數據類型(MIME類型)。它的四個屬性scheme、host、port、path對應於URI的每個部分: scheme://host:port/path。scheme的值一般為"http",host為包名,port為端口號,path為具體地址。
其中host和port合起來構成URI的憑據(authority),如果host沒有指定,則port也會被忽略。要讓authority有意義,scheme也必須要指定。要讓path有意義,scheme+authority也必須要指定。 - mimeType(指定數據類型),若mimeType為'Image',則會從Content Provider的指定地址中獲取image類型的數據。還有“video”等,若設置為video/mp4,則表示在指定地址中獲取mp4格式的video文件
- 而pathPattern和PathPrefix主要是為了格式化path所使用的
轉自: https://www.jianshu.com/p/1a8df0a8707c