APK安裝流程詳解1——有關(guān)"安裝ing"的實(shí)體類概述

APK安裝流程系列文章整體內(nèi)容如下:

本片文章主要內(nèi)容如下:

  • 1、AndroidManifest的另一種理解
  • 2、PackageInfo類簡(jiǎn)介
  • 3、PackageItemInfo類簡(jiǎn)介類
  • 4、ApplicationInfo類簡(jiǎn)介
  • 5、ComponentInfo類簡(jiǎn)介
  • 6、ActivityInfo類簡(jiǎn)介
  • 7、ServiceInfo類簡(jiǎn)介
  • 8、ProviderInfo類簡(jiǎn)介
  • 9、ResolveInfo類簡(jiǎn)介
  • 10、PermissionInfo類簡(jiǎn)介
  • 11、PermissionGroupInfo類簡(jiǎn)介
  • 12、上述這些類的關(guān)系
  • 13、Android中的UID、GID與GIDS的簡(jiǎn)介
  • 14、@GuardBy、@SystemApi、@hide Android注解簡(jiǎn)介

一、AndroidManifest的另一種理解

為了讓后面大家更好的理解安裝流程,本片文章先預(yù)熱下,說(shuō)到安裝就不能不說(shuō)下AndroidManifest.xml文件,因?yàn)樵蹅傾PK的的核心東西都在里面,但是它是一個(gè)"xml"文件,在安裝的時(shí)候,必然會(huì)把它序列化掉,那序列化后對(duì)應(yīng)的都是什么對(duì)象?為了便于理解,我從網(wǎng)站"借"了一張AndroidManifest.xml文件節(jié)點(diǎn)的說(shuō)明圖:

AndroidManifest文件節(jié)點(diǎn).png

下面我們根據(jù)上面的那張圖來(lái)依次把涉及到的類都詳細(xì)說(shuō)明下:

二、PackageInfo類簡(jiǎn)介

該類包含了從AndroidManifest.xml文件中收集的所有信息。
PackageInfo.java源碼地址
通過(guò)源碼我們知道PackageInfo是實(shí)現(xiàn)Parcelable接口,所以它可以在進(jìn)程間傳遞

1、重要成員變量簡(jiǎn)介

  • public String packageName:包名
  • public String versionName:版本名
  • public String versionCode:版本號(hào)
  • public String sharedUserId:共享用戶ID,簽名相同的情況下程序之間數(shù)據(jù)共享
  • public long firstInstallTime:第一次安裝時(shí)間,忽略之前安裝后卸載的情況單位ms
  • public long lastUpdateTime:最后更新時(shí)間,相同版本號(hào)的APK覆蓋安裝,該值也會(huì)發(fā)生變化,單位ms
  • public String[] requestedPermissions:請(qǐng)求的權(quán)限
  • public ApplicationInfo applicationInfo:Applicationinfo對(duì)象,下面會(huì)講解
  • public ActivityInfo[] activities:注冊(cè)的Activity
  • public ActivityInfo[] receivers:注冊(cè)的Receiver,PS:注意這里是ActivityInfo[]
  • public ServiceInfo[] services:注冊(cè)的服務(wù)
  • public ProviderInfo[] providers:注冊(cè)的Providers

2、重要方法簡(jiǎn)介

  • public PackageInfo():構(gòu)造函數(shù)
  • private PackageInfo(Parcel source):構(gòu)造函數(shù),反序列時(shí)用到的,注意這個(gè)方法是private,所以這個(gè)方法只是給反序列時(shí)用的,所以PackageInfo對(duì)外就提供一個(gè)構(gòu)造函數(shù)
  • private void propagateApplicationInfo(ApplicationInfo appInfo, ComponentInfo[] components):主要是給入?yún)⒌腸omponents中的每一項(xiàng)ComponentInfo的applicationInfo變量指向第一個(gè)入?yún)ppInfo。

三、PackageItemInfo類簡(jiǎn)介

PackageItemInfo類源碼位置

PackageItemInfo類:它是AndroidManifest.xml文件中所有節(jié)點(diǎn)的基類,代表一個(gè)應(yīng)用包內(nèi)所有組件和通用信息的基類。該類提供最基本的屬性集合,如:label、icon、meta等。一般不會(huì)直接用這個(gè)類,設(shè)計(jì)它的目的就是為包內(nèi)其他基本組件提供統(tǒng)一的基礎(chǔ)定義。它沒(méi)有實(shí)現(xiàn)接口Parcelable,但它提供了傳Parcel型的構(gòu)造函數(shù),以及writeToParcel()方法給它的子類來(lái)實(shí)現(xiàn)PackageItemInfo內(nèi)部的成員Parcel化。

1、重要成員變量簡(jiǎn)介:

  • public int icon:獲取該組件項(xiàng)在R文件中drawable的資源id值,對(duì)應(yīng)的是"android:icon"屬性,如果不設(shè)置為0。
  • public int labelRes:獲取該組件項(xiàng)在R文件中String型的資源idint值,對(duì)應(yīng)的是"android:label",如果不設(shè)置為0。
  • public String packageName:獲取該組件項(xiàng)的包名,對(duì)應(yīng)的是"android:packagename"屬性。
  • public String name:獲取該組件項(xiàng)的公共名稱,對(duì)應(yīng)的是"android:name"
  • public int banner:獲取該組件項(xiàng)在R文件中drawable的資源id值,對(duì)應(yīng)是"android:banner",不設(shè)置為0
  • public int logo:獲取該組件項(xiàng)在R文件中drawable的資源id值,比應(yīng)用圖標(biāo)要大,一般用在ToolBar上面,對(duì)應(yīng)是"android: logo",不設(shè)置為0
  • public Bundle metaData:對(duì)應(yīng)AndroidManifest中的<meta-data>標(biāo)簽。只有<activity>、<activity-alias>、<service>、<receiver>、<application>標(biāo)簽中可能包含<meta-data>子標(biāo)簽。
  • public int logo:獲取該組件項(xiàng)在R文件中drawable的資源id值,比應(yīng)用圖標(biāo)要大,一般用在ToolBar上面,對(duì)應(yīng)是"android: logo",不設(shè)置為0
  • public int showUserIcon:默認(rèn)值是serHandle.USER_NULL、也可能是
    UserHandle.USER_OWNER,只有實(shí)例的引用來(lái)訪問(wèn)

2、重要方法簡(jiǎn)介:

  • PackageItemInfo():構(gòu)造函數(shù)
  • public PackageItemInfo(PackageItemInfo orig):構(gòu)造函數(shù),傳入一個(gè)orig,進(jìn)行變量拷貝而已
  • protected PackageItemInfo(Parcel source):反序列化時(shí)用到的構(gòu)造函數(shù),注釋他是protected,說(shuō)只要是PackageItemInfo的子類局均可以調(diào)用
  • public CharSequence loadLabel(PackageManager pm):返回該組件項(xiàng)的標(biāo)簽,優(yōu)先級(jí)為:nonLocalizedLabel>labelRes>name>packageName
  • public Drawable loadIcon(PackageManager pm):獲取當(dāng)前組件的圖標(biāo),其實(shí)是通過(guò)PackageManager的loadItemIcon()來(lái)獲取的。
  • public Drawable loadBanner(PackageManager pm):獲取當(dāng)前組件的的banner,內(nèi)部是通過(guò)PackageManager的getDrawable()來(lái)獲取的banner對(duì)應(yīng)的Drawable,如果banner為0,返回loadDefaultBanner()的結(jié)果。
  • public Drawable loadLogo(PackageManager pm):返回該組件項(xiàng)的大圖標(biāo),通過(guò)PackageManager的getDrawable()方法獲取logo對(duì)應(yīng)的Drawable,如果logo為0,返回loadDefaultLogo()的結(jié)果。
  • public Drawable loadDefaultIcon(PackageManager pm):返回該組件項(xiàng)的默認(rèn)圖標(biāo),通過(guò)PackageManager的getDefaultActivityIcon()方法,返回的是com.android.internal.R.drawable.sym_def_app_icon對(duì)應(yīng)的Drawable。
  • protected Drawable loadDefaultBanner(PackageManager pm):返回null
  • protected Drawable loadDefaultLogo(PackageManager pm):返回null
  • public XmlResourceParser loadXmlMetaData(PackageManager pm, String name):找到metaData對(duì)應(yīng)為name的資源id,通過(guò)PackageManager的getXml()方法返回id對(duì)應(yīng)的XmlResourceParser。
  • protected ApplicationInfo getApplicationInfo():返回null
  • public void writeToParcel(Parcel dest, int parcelableFlags):為PackageItemInfo的子類Parcel化提供基類部分成員的寫(xiě)入。

四、ApplicationInfo類簡(jiǎn)介

ApplicationInfo類源碼位置

ApplicationInfo類:它繼承自PackageItemInfo并實(shí)現(xiàn)了Parcelable 接口,它對(duì)應(yīng)manifest里面的<application>節(jié)點(diǎn)的信息

1、特殊成員變量flags如下:

  • int flags:代表Application的類型,它是進(jìn)行"位與"操作的選項(xiàng),大家可以看下面的每一個(gè)只占用"1位":
    • FLAG_SYSTEM:系統(tǒng)應(yīng)用程序
    • FLAG_DEBUGGABLE:應(yīng)用程序允許debug,對(duì)應(yīng)manifest里面的android:debuggable屬性。
    • FLAG_HAS_CODE:應(yīng)用程序是否含有代碼,平時(shí)比較少用,如果,對(duì)應(yīng)manifest里面的android:hasCode,為true表明有代碼,為false表明代碼,如果沒(méi)有代碼則加載組件時(shí)系統(tǒng)不會(huì)嘗試加載任何應(yīng)用程序的代碼。應(yīng)用程序一般沒(méi)有它自己的任何代碼,除非它僅僅是由組件類的構(gòu)建而成的。
    • FLAG_PERSISTENT:應(yīng)用程序是否永久駐留,對(duì)應(yīng)manifest文件中的android:persistent="true",理論上意思是應(yīng)用程序所在進(jìn)程不會(huì)被LMK殺死。但是這里有個(gè)前提,就是應(yīng)用程序必須是系統(tǒng)應(yīng)用。也就是說(shuō)普通的應(yīng)用程序設(shè)置這個(gè)屬性其實(shí)是沒(méi)有用的。如果你的應(yīng)用程序的apk直接放到/system/app目錄下。而且必須重啟系統(tǒng)才能生效
    • FLAG_FACTORY_TEST:應(yīng)用程序支持Factory Test,關(guān)于Factory Test 這里就不詳細(xì)展開(kāi)了,有興趣的可以閱讀這篇文章Android FactoryTest框架
    • FLAG_ALLOW_TASK_REPARENTING:設(shè)置activity從一個(gè)task遷移到另一個(gè)task的標(biāo)簽,這塊后面在activity啟動(dòng)流程中會(huì)詳細(xì)講解,對(duì)應(yīng)的manifest文件是android:allowTaskReparenting。
    • FLAG_ALLOW_CLEAR_USER_DATA:設(shè)置用戶自動(dòng)清除數(shù)據(jù),對(duì)應(yīng)manifest中為android:allowClearUserData,該值設(shè)為true時(shí),用戶可以自己自己清除用戶數(shù)據(jù),反之則用戶不能清除。
    • FLAG_UPDATED_SYSTEM_APP: 表明系統(tǒng)應(yīng)用程序被用戶升級(jí)后,也算用戶的應(yīng)用程序
    • FLAG_TEST_ONLY:表示該應(yīng)用僅僅用于測(cè)試,對(duì)應(yīng)manifest里面的android:testOnly,如果設(shè)置為true,則表明僅僅用于測(cè)試
    • FLAG_SUPPORTS_SMALL_SCREENS: 設(shè)置應(yīng)用程序的window可以縮小到較小屏幕的大小,對(duì)應(yīng)的manifest里面的android:smallScreens,值為true,則表明可以縮小。
    • FLAG_SUPPORTS_NORMAL_SCREENS: 設(shè)置應(yīng)用程序的window可以在正常的屏幕上顯示,對(duì)應(yīng)的manifest里面的android:normalScreens,值為true,則表明可以顯示。
    • FLAG_SUPPORTS_LARGE_SCREENS: 設(shè)置應(yīng)用的window可以放大到較大屏幕的大小,對(duì)應(yīng)的manifest里面的android:largeScreens,值為true,則表明可以放大。
    • FLAG_RESIZEABLE_FOR_SCREENS: 設(shè)置應(yīng)用程序自己知道如何去適應(yīng)不同的屏幕密度,對(duì)應(yīng)manifest里面是android:anyDensity,值為true,則應(yīng)用程序自己調(diào)整。
    • FLAG_VM_SAFE_MODE: 設(shè)置應(yīng)用程序在安全模式下運(yùn)行VM,即不運(yùn)行JIT,對(duì)應(yīng)manifest里面的 android:vmSafeMode,值為true則設(shè)置為安全模式
    • FLAG_ALLOW_BACKUP: 設(shè)置允許操作系統(tǒng)備份數(shù)據(jù),對(duì)應(yīng)的manifest里面的android:allowBackup,設(shè)置true則允許備份
    • FLAG_KILL_AFTER_RESTORE: 這塊我也是不很清楚,設(shè)置在未來(lái)的某個(gè)事件點(diǎn)并且版本versionCode要大于當(dāng)前版本的versionCode,則可以處理還原數(shù)據(jù)。對(duì)應(yīng)的是manifest里面的android:restoreAnyVersion,值為true則設(shè)置。
    • FLAG_EXTERNAL_STORAGE:表明應(yīng)用程序安裝在SD卡上
    • FLAG_SUPPORTS_XLARGE_SCREENS:表明應(yīng)用程序的window可以增加尺寸適用于超大屏幕。在manifest里面對(duì)應(yīng)的android:xlargeScreens
    • FLAG_LARGE_HEAP:表明應(yīng)用程序?yàn)槠溥M(jìn)程要求申請(qǐng)更大的內(nèi)存堆。manifest里面對(duì)應(yīng)的是android:largeHeap
    • FLAG_STOPPED:表明這個(gè)應(yīng)用程序處于停止?fàn)顟B(tài)
    • FLAG_SUPPORTS_RTL: 表明應(yīng)用程序支持從右到左,所有Activity將變更為從右到左。
    • FLAG_INSTALLED:表明該當(dāng)前應(yīng)用程序是被當(dāng)前用戶安裝的。
    • FLAG_IS_DATA_ONLY:表明當(dāng)該應(yīng)用程序僅僅安裝其數(shù)據(jù),應(yīng)用程序包本身并不存在設(shè)備上。
    • FLAG_IS_GAME:表明當(dāng)該應(yīng)用程序是一個(gè)程序
    • FLAG_FULL_BACKUP_ONLY:表明定義一個(gè)android.app.backup.BackupAgent,通過(guò)這個(gè)BackupAgent對(duì)象來(lái)負(fù)責(zé)進(jìn)行應(yīng)用程序的全數(shù)據(jù)備份。
    • FLAG_USES_CLEARTEXT_TRAFFIC:表明該應(yīng)用程序的網(wǎng)絡(luò)請(qǐng)求是明文,對(duì)WebView無(wú)用,如果是在Android N上配置網(wǎng)絡(luò)配置,也無(wú)用。對(duì)應(yīng)manifest里面的android:usesCleartextTraffic
    • FLAG_EXTRACT_NATIVE_LIBS:表明從.apk中提取native庫(kù)
    • FLAG_HARDWARE_ACCELERATED:表明當(dāng)該應(yīng)用程序開(kāi)啟硬件加速渲染
    • FLAG_SUSPENDED:表明當(dāng)該應(yīng)用程序當(dāng)前處于掛起狀態(tài)
    • FLAG_MULTIARCH:表明當(dāng)前應(yīng)用程序的代碼需要加載到其他應(yīng)用程序的進(jìn)程中。

2、重要成員變量簡(jiǎn)介:

  • public String taskAffinity:和當(dāng)前應(yīng)用所有Activity的默認(rèn)task有密切關(guān)系,可以參考下面ActivityInfo的taskAffinity,可以通過(guò)AndroidManifest的"android:taskAffinity"屬性得到,具體taskAffinity是怎么影響到Activity在task的啟動(dòng),后面會(huì)在Activity啟動(dòng)模式中細(xì)講
  • public String permission:訪問(wèn)當(dāng)前應(yīng)用的所有組件需要聲明的權(quán)限,在AndroidManifest的"android:permission"屬性得到
  • public String processName:應(yīng)用運(yùn)行的進(jìn)程名,可以在AndroidManifest的"android:process"得到,如果沒(méi)有設(shè)置則默認(rèn)為應(yīng)用包名。
  • public String className:Application類的類名,可以在AndroidManifest的"android:class"屬性得到。
  • public int descriptionRes:對(duì)Application組件的描述,可以在AndroidManifest的"android:description"屬性得到,不設(shè)置則為0
  • public int theme:應(yīng)用的主題,可以在AndroidManifest的"android:theme"屬性得到,若不設(shè)置則為0。
  • public String manageSpaceActivityName:用于指定一個(gè)Activity來(lái)管理數(shù)據(jù),它最終會(huì)出現(xiàn)在"設(shè)置->應(yīng)用程序管理"中,默認(rèn)按鈕為"清楚數(shù)據(jù)",可以在AndroidManifest的屬性"android:manageSpaceActivity"中設(shè)置值,如果設(shè)定后,該按鈕可點(diǎn)擊跳轉(zhuǎn)到該Activity,讓用戶選擇性清除哪些數(shù)據(jù),若不設(shè)置則為null。
  • public String backupAgentName:Android原生的備份引擎BackupManagerService在應(yīng)用端的實(shí)現(xiàn)類,是backupAgent的子類。默認(rèn)不會(huì)由系統(tǒng)備份,可以在AndroidManifest屬性"android:backupAgent"得到,如果設(shè)置"android:allowBackup"為false,則該屬性設(shè)置無(wú)效。
  • public int fullBackupContent = 0:表明應(yīng)用是否支持自動(dòng)備份
  • public int uiOptions = 0:為應(yīng)用內(nèi)所有的Activity設(shè)置默認(rèn)的UI選項(xiàng),可選值為"none"、"splitActionBarWhenNarrow"。
  • *public String sourceDir:應(yīng)用APK的全路徑
  • public String publicSourceDir:sourceDir公開(kāi)可訪問(wèn)的部分,被forward lock鎖定的應(yīng)用該值可能與sourceDir不一樣
  • public String[] resourceDirs:如果當(dāng)前應(yīng)用有額外資源包時(shí),表示全路徑。通常為null。
  • public String seinfo:來(lái)自Linux策略中seiInfo標(biāo)簽,這個(gè)值一般在設(shè)置應(yīng)用進(jìn)程的SELinux安全上下文時(shí)有用。
  • public String dataDir:應(yīng)用數(shù)據(jù)目錄
  • public String dataDir:應(yīng)用JNI本地庫(kù)路徑
  • public int uid:Linux Kernel的user ID,目前對(duì)每個(gè)引用還不是唯一的,存在幾個(gè)應(yīng)用共享一個(gè)UID的情況。
  • public int targetSdkVersion:應(yīng)用最低目標(biāo)SDK版本號(hào)
  • public int versionCode:應(yīng)用的版本號(hào)
  • public boolean enabled = true:表明當(dāng)前應(yīng)用所有組件是否可用。

3、重要方法簡(jiǎn)介:

  • public ApplicationInfo():構(gòu)造函數(shù)
  • public ApplicationInfo(ApplicationInfo orig):構(gòu)造函數(shù),傳入一個(gè)ApplicationInfo,進(jìn)行拷貝。
  • private ApplicationInfo(Parcel source):私有的構(gòu)造函數(shù),序列化專用
  • protected ApplicationInfo getApplicationInfo():返回當(dāng)前ApplicationInfo對(duì)象
  • public boolean isSystemApp():判斷當(dāng)前應(yīng)用是否為系統(tǒng)應(yīng)用。flags與ApplicationInfo.FLAG_SYSTEM按位與不等于0則返回true。
  • public boolean isForwardLocked():判斷當(dāng)前應(yīng)用是否被鎖定。flags與ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK按位與不等于0則返回true。

五、ComponentInfo類簡(jiǎn)介

ComponentInfo.java

ComponentInfo,它代表一個(gè)應(yīng)用內(nèi)部的組件(如ActivityInfo、ServiceInfo、ProviderInfo),一般不會(huì)直接使用這個(gè)類,它被設(shè)計(jì)出來(lái)是為了不同應(yīng)用的組件共享統(tǒng)一的定義。它繼承與PackageItemInfo,但它不像ApplicationInfo一樣實(shí)現(xiàn)了Parcelable接口。它是沒(méi)有實(shí)現(xiàn)Parcelable接口,但是它提供了入?yún)⑹荘arcel的構(gòu)造函數(shù),以及writeToParcel()方法給它的子類來(lái)實(shí)現(xiàn)ComponentInfo內(nèi)部這部分的成員的Parcel化。

1、重要成員變量簡(jiǎn)介:

  • public ApplicationInfo applicationInfo:組件所在的application/package信息,從<application>標(biāo)簽得到。
  • public String processName:組件所運(yùn)行的進(jìn)程名稱,String類型,從"android:process"屬性得到
  • public int descriptionRes:組件的描述,string型的資源id,從"android:description",如果不設(shè)置則為0。
  • public boolean enabled:當(dāng)前組件是否被實(shí)例化,boolean類型,從"android:enabled"屬性得到,如果它所在的Application中的enable為false,則這處的設(shè)置無(wú)效。
  • public boolean exported:當(dāng)前組件能否被其他Application的組件啟動(dòng),boolean類型,可以從"android:exported"屬性得到。
    • 如果當(dāng)前組件沒(méi)有一個(gè)<intent-filter>則它默認(rèn)為false(沒(méi)有任何<intent-filter>表明要組件的準(zhǔn)確名稱來(lái)啟動(dòng)),exported=false表明當(dāng)前組件只能被當(dāng)前應(yīng)用內(nèi)組件啟動(dòng),或者有相同的UID的應(yīng)用。
    • 當(dāng)然也可以使用permission來(lái)限制外部應(yīng)用對(duì)組件的訪問(wèn),如果該組件有"android:permission"屬性,則訪問(wèn)這必須聲明該權(quán)限。當(dāng)該組件無(wú)permission屬性而<application>標(biāo)簽有聲明時(shí),則訪問(wèn)者必須有<application>簽名的permisson。

2、重要方法簡(jiǎn)介:

  • public ComponentInfo():構(gòu)造函數(shù)
  • public ComponentInfo(ComponentInfo orig):構(gòu)造函數(shù),傳入一個(gè)ComponentInfo,其實(shí)就是拷貝
  • protected ComponentInfo(Parcel source):構(gòu)造函數(shù),傳入一個(gè)source,然后從source里面取出相應(yīng)的值來(lái)完成字段的初始化
  • public CharSequence loadLabel(PackageManager pm):返回該組件的標(biāo)簽,CharSequence類型,優(yōu)先級(jí)次序?yàn)椋簄onLocalizedLabel>labelRes>applicationInfo.nonLocalizedLabel>applicationInfo.labelRes
  • public boolean isEnable():該組件是否啟動(dòng)該組件及包含的應(yīng)用程序,有且只有當(dāng)enabled和applicationInfo.enable同時(shí)為true時(shí),返回true。
  • public final int getIconResource():返回該組件的icon的資源id,類型是int,如果是0,則返回applicationInfo對(duì)應(yīng)的資源id
  • public final int getLogoResource():返回該組件的logo對(duì)應(yīng)的資源id,如果沒(méi)有,則返回applicationInfo對(duì)應(yīng)的資源id。
  • public final int getBannerResource():返回該組件banner對(duì)應(yīng)的資源id,如果沒(méi)有,則返回applicationInfo對(duì)應(yīng)的資源id。
  • @hide public Drawable loadDefaultIcon(PackageManager pm):返回組件默認(rèn)的icon,類型是Drawable,返回的是applicationInfo的loadIcon()
  • @hide protected Drawable loadDefaultBanner(PackageManager pm):返回組件默認(rèn)的banner,類型是Drawable,返回的是applicationInfo的loadBanner()
  • @hide protected Drawable loadDefaultLogo(PackageManager pm):返回組件默認(rèn)的logo,類型是Drawable,返回的是applicationInfo的loadLogo()
  • @hide protected ApplicationInfo getApplicationInfo():返回該組件的applicationInfo
  • public void writeToParcel(Parcel dest, int parcelableFlags):先調(diào)用父類PackageItemInfo的writeToParcel()方法,再完成自己的成員Parcel化

六、ActivityInfo類簡(jiǎn)介

ActivityInfo.java

ActivityInfol類
ApplicationInfo類:它繼承自ComponentInfo并實(shí)現(xiàn)了Parcelable 接口,它對(duì)應(yīng)manifest里面的<activity>或者<receiver>節(jié)點(diǎn)的信息。我們可以通過(guò)它來(lái)設(shè)置我們的任何屬性,包括theme、launchMode等,常用方法繼承至PackageItemInfo類中的loadIcon()和loadLabel()

1、重要成員變量簡(jiǎn)介:

  • public int launchMode:Activity的啟動(dòng)模式,對(duì)應(yīng)Manifest的"launchMode"屬性,可能是以下幾種模式:
    • public static final int LAUNCH_MULTIPLE = 0:普通模式
    • public static final int LAUNCH_SINGLE_TOP = 1:同一個(gè)task如果是頂部,復(fù)用
    • public static final int LAUNCH_SINGLE_TASK = 2:同一個(gè)task,無(wú)論是不是在頂部都復(fù)用
    • public static final int LAUNCH_SINGLE_INSTANCE = 3:新開(kāi)一個(gè)task
  • public int documentLaunchMode:總覽畫(huà)面--overview screenActivity的啟動(dòng)模式,關(guān)于總覽畫(huà)面可以參考 Android 5.0 Overview Screen--總覽畫(huà)面,對(duì)應(yīng)AndroidManifest里面的"documentLaunchMode"屬性,如果一個(gè)Activity添加了這個(gè)屬性,則該Activity被啟動(dòng)時(shí)永遠(yuǎn)會(huì)創(chuàng)建一個(gè)新的task。該屬性有4個(gè)值,用戶在應(yīng)用中打開(kāi)的一個(gè)document會(huì)有不同的效果如下:
    • public static final int DOCUMENT_LAUNCH_NONE = 0:
      Activity不會(huì)為document創(chuàng)建新的task,App設(shè)置為single task模式。它會(huì)重新調(diào)用用戶喚醒的所有activity中的最近的一個(gè)。
    • public static final int DOCUMENT_LAUNCH_INTO_EXISTING = 1:
      activity 會(huì)為該document請(qǐng)求一個(gè)已經(jīng)存在的task
    • public static final int DOCUMENT_LAUNCH_ALWAYS = 2:
      即使docutment已經(jīng)開(kāi)打了,activity也會(huì)為document創(chuàng)建一個(gè)新的task。
    • public static final int DOCUMENT_LAUNCH_NEVER = 3:
      activity不會(huì)為document創(chuàng)建一個(gè)新的task。
  • public int persistableMode:activity持久化的模式,對(duì)應(yīng)著AndroidManifest的"android:persistableMode"屬性,它有三個(gè)模式如下:
    • public static final int PERSIST_ROOT_ONLY = 0:
      默認(rèn)值,僅僅會(huì)作用在跟activity活著task中。
    • public static final int PERSIST_NEVER = 1:
      不起作用,不用兩個(gè)持久化頁(yè)面數(shù)據(jù)或狀態(tài)
    • public static final int PERSIST_ACROSS_REBOOTS = 2:
      重啟設(shè)備或持久化頁(yè)面的數(shù)據(jù)或者狀態(tài),如果在這個(gè)界面上的界面也設(shè)置這個(gè)值,上面的頁(yè)面也會(huì)被持久化,最后系統(tǒng)會(huì)將你保存的數(shù)據(jù),在重新打開(kāi)這個(gè)頁(yè)面的時(shí)候,會(huì)調(diào)用onCreate()具有兩個(gè)參數(shù)的方法。你只要在你第二個(gè)參數(shù)PersistableBundle中取出你保存的數(shù)據(jù)就可以了
  • public String requestedVrComponent;:跑在Activity上面的VrListenerService的組件名稱。
  • public int screenOrientation:表示Activity運(yùn)行的屏幕的方向。對(duì)應(yīng)AndroidManifest里面的"android:screenOrientation"屬性,具體屬性值如下:
    • public static final int SCREEN_ORIENTATION_UNSPECIFIED:未指定,它是默認(rèn)值,由Android系統(tǒng)自己選擇適當(dāng)?shù)姆较颍x擇策略是具體設(shè)備的配置情況而定,因此不同的設(shè)備會(huì)有不同的方向選擇。
    • public static final int SCREEN_ORIENTATION_LANDSCAPE:表示橫屏,顯示時(shí)寬度大于高度
    • public static final int SCREEN_ORIENTATION_PORTRAIT:表示書(shū)評(píng),顯示時(shí)高度大于寬度
    • public static final int SCREEN_ORIENTATION_USER:表示用戶當(dāng)前的首選方向。
    • public static final int SCREEN_ORIENTATION_BEHIND:表示用戶繼續(xù)Activity堆棧中當(dāng)前Activity下面的那個(gè)Activity的方向。
    • public static final int SCREEN_ORIENTATION_SENSOR:表示由物理感應(yīng)器決定顯示方向,它取決于用戶如何持有設(shè)備,當(dāng)設(shè)備被旋轉(zhuǎn)時(shí)方向會(huì)隨之變化——在橫屏和豎屏之間切換
    • public static final int SCREEN_ORIENTATION_NOSENSOR:忽略物理感應(yīng)器——即顯示方向和物理感應(yīng)器無(wú)關(guān),不管用戶如何旋轉(zhuǎn)設(shè)備,顯示方向都不會(huì)發(fā)生改變。
    • public static final int SCREEN_ORIENTATION_SENSOR_LANDSCAPE:表示Activity在橫向屏幕上顯示,但是可以根據(jù)方向傳感器的指示來(lái)進(jìn)行改變
    • public static final int SCREEN_ORIENTATION_SENSOR_PORTRAIT:表示Activity在縱向屏幕上顯示,可以根據(jù)方向傳感器指示的方向來(lái)進(jìn)行改變。
    • public static final int SCREEN_ORIENTATION_REVERSE_LANDSCAPE:表示Activity橫屏顯示,當(dāng)時(shí)與正常的橫屏方向相反(比如原來(lái)很平方向是向左的,這時(shí)候也是橫屏但是方向向右)
    • public static final int SCREEN_ORIENTATION_REVERSE_PORTRAIT:表示Activity豎屏顯示,但是與正常的縱向方向的屏幕方向相反
    • public static final int SCREEN_ORIENTATION_FULL_SENSOR:表示Activity的方向由方向傳感器決定,會(huì)根據(jù)用戶設(shè)備的移動(dòng)情況來(lái)旋轉(zhuǎn)

七、ServiceInfo類簡(jiǎn)介

ServiceInfo.java源碼地址

ServiceInfo類,它繼承自ComponentInfo并實(shí)現(xiàn)了Parcelable接口,它對(duì)應(yīng)manifest里面的<service>節(jié)點(diǎn)的信息。

1、重要成員變量簡(jiǎn)介:

  • public String permission:這個(gè)Service的訪問(wèn)權(quán)限
  • public int flags:表示service在AndroidManifest設(shè)置的選項(xiàng)
    • public static final int FLAG_STOP_WITH_TASK:如果用戶刪除了預(yù)計(jì)應(yīng)程序的Activitiest,系統(tǒng)將自動(dòng)停止這個(gè)Service
    • public static final int FLAG_ISOLATED_PROCESS:Service在其獨(dú)立的進(jìn)程中運(yùn)行
    • public static final int FLAG_EXTERNAL_SERVICE:這個(gè)?Service可以被外部包調(diào)用
    • public static final int FLAG_SINGLE_USER:表示Service就是一個(gè)單例。

方法很少且很簡(jiǎn)單,這里就不講解了

八、ProviderInfo類簡(jiǎn)介

ProviderInfo.java源碼地址

ProviderInfo類,它繼承自ComponentInfo并實(shí)現(xiàn)了Parcelable接口,它對(duì)應(yīng)manifest里面的<provider>節(jié)點(diǎn)的信息。

1、重要成員變量簡(jiǎn)介:

  • public String authority:提供者的名字
  • public String readPermission:只讀的provider的訪問(wèn)權(quán)限
  • public String writePermission:讀寫(xiě)的provider的訪問(wèn)權(quán)限
  • public boolean grantUriPermissions:是否授予provider提供特定的Uris訪問(wèn)權(quán)限
  • public PatternMatcher[] uriPermissionPatterns:provider的PatternMatcher數(shù)組
  • public PathPermission[] pathPermissions:provider的PathPermission數(shù)組
  • public boolean multiprocess = false:是否允許多進(jìn)程多實(shí)例
  • public int initOrder = 0:同一個(gè)進(jìn)程運(yùn)行的的provider的初始順序,數(shù)字越高,優(yōu)先級(jí)越高
  • public int flags:provider的選項(xiàng)
    • public static final int FLAG_SINGLE_USER = 0x40000000:設(shè)置為provider為單例模式。

方法很少且很簡(jiǎn)單,這里就不講解了

九、ResolveInfo類簡(jiǎn)介

ResolveInfo.java源碼地址

ResolveInfo就是解析 intent過(guò)程返回的信息,也是通過(guò)解析一個(gè)IntentFilter相對(duì)應(yīng)的intent得到的信息。它部分的對(duì)應(yīng)位于AndroidManifest.xml的<intent>標(biāo)簽收集到的信息,ResolveInfo實(shí)現(xiàn)了Parcelable接口。

1、重要成員變量簡(jiǎn)介:

  • public ActivityInfo activityInfo:和Intent相匹配的ActivityInfo(可能是Activity或者Receiver)
  • public ServiceInfo serviceInfo:和Intent相匹配的serviceInfo
  • public ProviderInfo providerInfo:和Intent相匹配的providerInfo
  • public IntentFilter filter:匹配的IntentFilter
  • public int priority:匹配優(yōu)先級(jí),數(shù)字越高,優(yōu)先級(jí)約高,默認(rèn)是0
  • public int preferredOrder:用戶配置的優(yōu)先級(jí),默認(rèn)是0,數(shù)值越大,優(yōu)先級(jí)越高
  • public int match:系統(tǒng)評(píng)估Activity與Intent的匹配程度,是一個(gè)數(shù)字。
  • public int specificIndex = -1:如果設(shè)置了queryIntentActivityOptions,這個(gè)specificIndex表示返回列表的下標(biāo),0 是列表的第一個(gè)。<0則表示它來(lái)自通用的Intent查詢。
  • public boolean isDefault:是否在過(guò)濾器中制定了Intent.CATEGORY_DEFAULT,意味著它被用戶可以對(duì)數(shù)據(jù)進(jìn)行默認(rèn)的操作

2、重要方法簡(jiǎn)介:

  • public ResolveInfo():構(gòu)造函數(shù)
  • public ResolveInfo(ResolveInfo orig):帶有ResolveInfo的構(gòu)造函數(shù),進(jìn)行數(shù)據(jù)拷貝
  • private ResolveInfo(Parcel source):私有的構(gòu)造函數(shù)主要是給反序列化的時(shí)候。
  • **public CharSequence loadLabel(PackageManager pm) **:獲取標(biāo)簽,獲取優(yōu)先級(jí)順序如下:nonLocalizedLabel>labelRes(resolvePackageName)>labelRes(ci.packageName)> ci.loadLabel(pm)
  • **public Drawable loadIcon(PackageManager pm) *:獲取Drawable類型的圖標(biāo)。
  • final int getIconResourceInternal():注意這個(gè)方法的作用域是"包內(nèi)",返回匹配的圖標(biāo)資源標(biāo)識(shí)符,如果匹配了直接使用,沒(méi)有匹配使用應(yīng)用程序圖標(biāo)
  • public final int getIconResource():返回匹配的圖標(biāo)資源標(biāo)識(shí)符,如果沒(méi)有匹配就使用應(yīng)用程序圖標(biāo)。

十、PermissionInfo類簡(jiǎn)介

PermissionInfo.java

PermissionInfo,它代表一個(gè)應(yīng)用的權(quán)限描述,它既是權(quán)限信息的記錄,也是權(quán)限的級(jí)別保護(hù),在Android系統(tǒng)中,做任何操作都要申請(qǐng)權(quán)限,但是如果你的級(jí)別不夠,有些權(quán)限不是你在代碼中寫(xiě)了申請(qǐng)就能獲取的。在使用PermissionInfo來(lái)指定一個(gè)權(quán)限的基本信息時(shí),需要指定protectedLevel,并指定所屬的group信息。PermissionInfo繼承自PackageItemInfo,并實(shí)現(xiàn)了Parcelable接口。

1、重要成員變量簡(jiǎn)介:

  • public int protectionLevel:保護(hù)權(quán)限的級(jí)別,可以是如下級(jí)別
    • public static final int PROTECTION_NORMAL:表示只要是申請(qǐng)了就可以使用的級(jí)別。
    • public static final int PROTECTION_DANGEROUS:表示在安裝時(shí)需要用戶確認(rèn)才可以使用
    • public static final int PROTECTION_SIGNATURE:表示使用者的APP和系統(tǒng)使用同一個(gè)證書(shū),即系統(tǒng)權(quán)限級(jí)別
  • public String group:權(quán)限組
  • public int flags:附加權(quán)限的標(biāo)志位,可能是以下幾個(gè)值:
    • FLAG_COSTS_MONEY:付費(fèi)標(biāo)志
    • FLAG_REMOVED:刪除標(biāo)志
    • FLAG_INSTALLED:安裝標(biāo)志
  • public int descriptionRes:資源中的表示權(quán)限的描述

2、重要方法簡(jiǎn)介:

  • public PermissionInfo():構(gòu)造函數(shù)
  • public PermissionInfo(PermissionInfo orig):帶有PermissionInfo的構(gòu)造函數(shù),進(jìn)行數(shù)據(jù)拷貝
  • private PermissionInfo(Parcel source):私有的構(gòu)造函數(shù)主要是給反序列化的時(shí)候。

十一、PermissionGroupInfo簡(jiǎn)介

PermissionGroupInfo.java

PermissionGroupInfo類,它表示一個(gè)權(quán)限組的概念,Android系統(tǒng)內(nèi)部定了很多權(quán)限組,比如android.permission-group.CONTACTS表示聯(lián)系人相關(guān)權(quán)限組。PermissionGroupInfo繼承自PackageItemInfo,并實(shí)現(xiàn)了Parcelable接口。

1、已知的權(quán)限組如下:

  • android.permission-group.CONTACTS:聯(lián)系人相關(guān)權(quán)限組
  • android.permission-group.PHONE:電話相關(guān)權(quán)限組
  • android.permission-group.APPSTORE_CLOUD:應(yīng)用商店云服務(wù)相關(guān)權(quán)限組
  • android.permission-group.CALENDAR:日歷相關(guān)權(quán)限組
  • android.permission-group.CAMERA:相機(jī)相關(guān)權(quán)限組
  • android.permission-group.SENSORS:傳感器相關(guān)權(quán)限組
  • android.permission-group.LOCATION:位置服務(wù)相關(guān)權(quán)限組
  • android.permission-group.STORAGE:存儲(chǔ)相關(guān)權(quán)限組
  • android.permission-group.MICROPHONE:話筒相關(guān)權(quán)限組
  • android.permission-group.SMS:短消息相關(guān)權(quán)限組

2、重要成員變量簡(jiǎn)介:

  • public String nonLocalizedDescription:如果這個(gè)權(quán)限組的名字字符串直接定義在AndroidManifest.xml中,那么通過(guò)這個(gè)值可以得到他的名字(String類型),如果是空,則是調(diào)用的資源使用descriptionRes
  • public int descriptionRes:資源中的表示權(quán)限組的描述
  • public int flags:權(quán)限組的標(biāo)志位
  • public int priority:權(quán)限組的優(yōu)先級(jí):

十二、上述這些類的關(guān)系

關(guān)于主要成員就介紹到這里,看下他們對(duì)應(yīng)的關(guān)系,如下圖:

對(duì)應(yīng)關(guān)系1.png
對(duì)應(yīng)關(guān)系2.png

上一篇文章APK安裝流程詳解0——前言
下一篇文章APK安裝流程詳解2——PackageManager簡(jiǎn)介

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,520評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,362評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,805評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,541評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,896評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,062評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,608評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,356評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,555評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,769評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,175評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,489評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,289評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,516評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容