APK安裝流程系列文章整體內容如下:
- APK安裝流程詳解0——前言
- APK安裝流程詳解1——有關"安裝ing"的實體類概述
- APK安裝流程詳解2——PackageManager簡介
- APK安裝流程詳解3——PackageManager與PackageManagerService
- APK安裝流程詳解4——安裝中關于so庫的那些事
- APK安裝流程詳解5——PackageInstallerService和Installer
- APK安裝流程詳解6——PackageManagerService啟動前奏
- APK安裝流程詳解7——PackageManagerService的啟動流程(上)
- APK安裝流程詳解8——PackageManagerService的啟動流程(下)
- APK安裝流程詳解9——PackageParser解析APK(上)
- APK安裝流程詳解10——PackageParser解析APK(下)
- APK安裝流程詳解11——普通應用安裝簡介
- APK安裝流程詳解12——PackageManagerService中的新安裝流程上(拷貝)
- APK安裝流程詳解13——PackageManagerService中的新安裝流程下(裝載)
- APK安裝流程詳解14——PMS中的新安裝流程上(拷貝)補充
- APK安裝流程詳解15——PMS中的新安裝流程下(裝載)補充
- APK安裝流程詳解16——Android包管理總結
本片文章的主要內容如下:
- 1、PackageManager的具體實現類
- 2、ApplicationPackageManager類
- 3、IPackageManager類
- 4、PackageMnager、IPackageManager與PackageManagerService
- 5、PackageManagerService類簡介
- 6、ServiceManager與PackageManagerService關系
- 7、總結
一、PackageManager的具體實現類
上面一篇文章介紹了PackageManager,我們知道PackageManager是一個抽象類,它里面很重要的方法都是抽象的,所以在具體執行的時候,肯定是他的實現子類,那么我們就來看下他具體實現類,上面一篇文章我們研究PackageManager類的時候,官網推薦獲取PackageManager對象的方法是Context的Context#getPackageManager()方法,那我們來看下
1、Context#getPackageManager()
代碼在Context.java 322行
/** Return PackageManager instance to find global package information. */
public abstract PackageManager getPackageManager();
我們知道Context是一個抽象類,而他的getPackageManager()也是抽象方法,我們知道Context的具體實現類是ContextImpl,那我們就去ContextImpl里面去看下
2、ContextImpl#getPackageManager()
代碼在ContextImpl.java 208行
@Override
public PackageManager getPackageManager() {
// 第一步
if (mPackageManager != null) {
return mPackageManager;
}
// 第二步
IPackageManager pm = ActivityThread.getPackageManager();
// 第三步
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
這個方法的內部流程大體上分為三個步驟如下:
- 第一步:判斷mPackageManager是否為空,如果為空,則說明是的第一次調用,走第二步,如果不為空,則直接返回mPackageManager
- 第二步:能走到第二步,說明這是第一次調用,則調用ActivityThread的靜態方法getPackageManager()獲取一個IPackageManager對象
- 第三步:如果獲取的IPackageManager對象不為空,則構造一個ApplicationPackageManager對象,而ApplicationPackageManager是PackageManager的子類,把mPackageManager指向ApplicationPackageManager,然后返回ApplicationPackageManager,也就是返回的ApplicationPackageManager
通過上面代碼分析我們知道,在我們平時調用Context的getPackageManager()方法返回的是ApplicationPackageManager這個類。
在這個方法里面涉及到兩個重要類:
- 1、ActivityThread.getPackageManager()中的返回值IPackageManager類
- 2、new ApplicationPackageManager(this, pm)中的ApplicationPackageManager類
下面我就依次研究下,首先看下ApplicationPackageManager類
二、ApplicationPackageManager類
ApplicationPackageManager.java源碼地址
1、ApplicationPackageManager類簡介
final class ApplicationPackageManager extends PackageManager {
...
}
通過源代碼我們知道ApplicationPackageManager繼承自PackageManager,而且這ApplicationPackageManager類不是抽象的,所以ApplicationPackageManager必然實現了PackageManager的所有抽象方法,而且ApplicationPackageManager是final的,所以它沒有子類。
2、ApplicationPackageManager類的構造函數
ApplicationPackageManager就一個構造函數
代碼在ApplicationPackageManager.java 1123行
ApplicationPackageManager(ContextImpl context,
IPackageManager pm) {
mContext = context;
mPM = pm;
}
- 1、這個構造函數不是public所以,只能它的活動區域只有"包"內,而它的包是"android.app",而且它的構造函數就一個,所以只有系統才能調用。
- 2、兩個入參,一個是ContextImpl,一個IPackageManager對象。關于IPackageManager對象,我們下面將仔細講解。
3、ApplicationPackageManager類中對PackageManager的具體實現
我們首先來看和安裝有關的幾個方法
- 1、public abstract void installPackage(Uri, IPackageInstallObserver, int,String)方法
- 2、 public abstract void installPackageWithVerification(Uri,IPackageInstallObserver, int, String,Uri, ManifestDigest,ContainerEncryptionParams)方法
- 3、public abstract void installPackageWithVerificationAndEncryption(Uri,IPackageInstallObserver, int, String, VerificationParams, ContainerEncryptionParams)方法
- 4、 public abstract void installPackage(Uri,PackageInstallObserver,int, String)方法
- 5、public abstract void installPackageWithVerification(Uri,PackageInstallObserver, int, String, Uri, ManifestDigest,ContainerEncryptionParams)方法
- 6、public abstract void installPackageWithVerificationAndEncryption(Uri,PackageInstallObserver, int, String,VerificationParams, ContainerEncryptionParams)方法
- 7、public abstract int installExistingPackage(String)方法
那我們就依次來看下
3.1、public abstract void installPackage(Uri, IPackageInstallObserver, int,String)方法
代碼在ApplicationPackageManager.java) 1335行
@Override
public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,String installerPackageName) {
// 第一步
final VerificationParams verificationParams = new VerificationParams(null, null,
null, VerificationParams.NO_UID, null);
// 第二步
installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
installerPackageName, verificationParams, null);
}
這個方法內部主要分為兩塊
- 第一步,構造VerificationParams對象
- 第二步,調用installCommon(Uri,PackageInstallObserver, int, String, int)方法
那我們就來看下installCommon(Uri,PackageInstallObserver, int, String, int)方法
代碼在ApplicationPackageManager.java) 1388行
private void installCommon(Uri packageURI,PackageInstallObserver observer, int flags, String installerPackageName, int userId) {
// 第一步
if (!"file".equals(packageURI.getScheme())) {
throw new UnsupportedOperationException("Only file:// URIs are supported");
}
// 第二步
final String originPath = packageURI.getPath();
try {
// 第三步
mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName,
userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
通過上面代碼我們知道,方法內部主要分為三個部分,如下:
- 第一步,scheme判斷,如果非"file"則拋異常,因為只支持file格式的URI
- 第二步,獲取相應的路徑
- 第三步,調用IPackageMnager的installPackageAsUser(String, IPackageInstallObserver2,int, String, int)方法
所以我們總結下就是:
public abstract void installPackage(Uri, IPackageInstallObserver, int,String)方法其內部本質是調用的IPackageManager的nstallPackageAsUser(String, IPackageInstallObserver2,int, String, int)
3.2、 public abstract void installPackageWithVerification(Uri,IPackageInstallObserver, int, String,Uri, ManifestDigest,ContainerEncryptionParams)方法
代碼在ApplicationPackageManager.java) 1344行
@Override
public void installPackageWithVerificationAndEncryption(Uri packageURI,IPackageInstallObserver observer, int flags, String installerPackageName,VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
installerPackageName, verificationParams, encryptionParams);
}
我們發現這個方法內部其實也是調用的是installCommon(Uri,PackageInstallObserver, int, String, int)方法,通過上面的內容我們知道,所以我們可以說
public abstract void installPackageWithVerification(Uri,IPackageInstallObserver, int, String,Uri, ManifestDigest,ContainerEncryptionParams)方法其內部本質也是調用的IPackageManager的installPackageAsUser(String, IPackageInstallObserver2,int, String, int)方法
3.3、 public abstract void installPackageWithVerificationAndEncryption(Uri,IPackageInstallObserver, int, String, VerificationParams, ContainerEncryptionParams)方法
代碼在ApplicationPackageManager.java) 1353行
@Override
public void installPackageWithVerificationAndEncryption(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
installerPackageName, verificationParams, encryptionParams);
}
我們發現這個方法內部其實也是調用的是installCommon(Uri,PackageInstallObserver, int, String, int)方法,通過上面的內容我們知道,所以我們可以說
public abstract void installPackageWithVerificationAndEncryption(Uri,IPackageInstallObserver, int, String, VerificationParams, ContainerEncryptionParams)方法其內部本質也是調用的IPackageManager的installPackageAsUser(String, IPackageInstallObserver2,int, String, int)方法
3.4、 public abstract void installPackage(Uri,PackageInstallObserver,int, String)方法
代碼在ApplicationPackageManager.java) 1362行
@Override
public void installPackage(Uri packageURI, PackageInstallObserver observer,int flags, String installerPackageName) {
// 第一步
final VerificationParams verificationParams = new VerificationParams(null, null,
null, VerificationParams.NO_UID, null);
// 第二步
installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null);
}
這個方法內部主要分為兩塊
- 第一步,構造VerificationParams對象
- 第二步,調用installCommon(Uri,PackageInstallObserver, int, String, int)方法
所以我們可以說
public abstract void installPackage(Uri,PackageInstallObserver,int, String)方法其內部本質也是調用的IPackageManager的installPackageAsUser(String, IPackageInstallObserver2,int, String, int)方法
3.5、public abstract void installPackageWithVerification(Uri,PackageInstallObserver, int, String, Uri, ManifestDigest,ContainerEncryptionParams)方法
代碼在ApplicationPackageManager.java) 1370行
@Override
public void installPackageWithVerification(Uri packageURI,PackageInstallObserver observer, int flags, String installerPackageName,Uri verificationURI, ManifestDigest manifestDigest,ContainerEncryptionParams encryptionParams) {
// 第一步
final VerificationParams verificationParams = new VerificationParams(verificationURI, null,null, VerificationParams.NO_UID, manifestDigest);
// 第二步
installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
encryptionParams);
這個方法內部主要分為兩塊
- 第一步,構造VerificationParams對象
- 第二步,調用installCommon(Uri,PackageInstallObserver, int, String, int)方法
所以我們可以說
public abstract void installPackageWithVerification(Uri,PackageInstallObserver, int, String, Uri, ManifestDigest,ContainerEncryptionParams)方法其內部本質也是調用的IPackageManager的installPackageAsUser(String, IPackageInstallObserver2,int, String, int)方法
3.6、public abstract void installPackageWithVerificationAndEncryption(Uri,PackageInstallObserver, int, String,VerificationParams, ContainerEncryptionParams)方法
代碼在ApplicationPackageManager.java) 1380行
@Override
public void installPackageWithVerificationAndEncryption(Uri packageURI,PackageInstallObserver observer, int flags, String installerPackageName,VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
encryptionParams);
}
我們發現這個方法內部其實也是調用的是installCommon(Uri,PackageInstallObserver, int, String, int)方法,通過上面的內容我們知道,所以我們可以說
public abstract void installPackageWithVerificationAndEncryption(Uri,PackageInstallObserver, int, String,VerificationParams, ContainerEncryptionParams)方法其內部本質也是調用的IPackageManager的installPackageAsUser(String, IPackageInstallObserver2,int, String, int)方法
3.6、public abstract int installExistingPackage(String)方法
代碼在ApplicationPackageManager.java) 147行
@Override
public int installExistingPackage(String packageName)
throws NameNotFoundException {
try {
// 第一步
int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
// 第二步
if (res == INSTALL_FAILED_INVALID_URI) {
throw new NameNotFoundException("Package " + packageName + " doesn't exist");
}
return res;
} catch (RemoteException e) {
// 第三步
// Should never happen!
throw new NameNotFoundException("Package " + packageName + " doesn't exist");
}
}
我們把這個方法內內部代碼大體上分為3塊如下:
- 第一步:首先調用IPackageMnager的installExistingPackageAsUser(String,int)方法,并將返回值賦值給res
- 第二步:如果res等于INSTALL_FAILED_INVALID_URI,則表示是無用的URI,并拋異常
- 第三步:如果走到這一步,則說明,在調用IPackageMnager的installExistingPackageAsUser(String,int)方法的時候拋RemoteException異常,則拋出異常說明。
通過上面的方法,大家有沒有發現什么規律,對了就是ApplicationPackageManager實現的PackageManager的抽象方法,其內部都是調用其內部變量mPm即IPackageManager類來實現的,大家可自行去看下,并驗證下。
4、總結
ApplicationPackageManager 中關于PackageManager的具體實現,其實是調用IPackageManager來是實現的。
那IPackageManager是什么東西,那我們來研究下
三、IPackageManager類
首先,我們先來看下上面代碼涉及到的ActivityThread.getPackageManager()方法內部是怎么實現的
(一)、ActivityThread的靜態方法getPackageManager()
關于ActivityThread我們會在后續的Android系統中的啟動流程中詳細講解。
代碼在ActivityThread.java 1669行
public static IPackageManager getPackageManager() {
//第一步
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
// 第二步
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
// 第三步
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
這個方法的內部流程大體上分為三個步驟如下:
- 第一步:判斷sPackageManager是否為空,如果為空,則說明是的第一次調用,走第二步,如果不為空,則直接返回sPackageManager
- 第二步:能走到第二步,說明這是第一次調用,則調用ServiceManager的getService(String)方法獲取一個IBinder對象
- 第三步:通過調用IPackageManager.Stub.asInterface(IBinder);獲取一個sPackageManager對象
咦,上面代碼好熟悉啊,這不是明顯的AIDL啊,這里涉及到Binder知識,可以參考我的Binder文章Android跨進程通信IPC之6——Binder框架和關于AIDL文章Android跨進程通信IPC之11——AIDL
(二)、IPackageManager.aidl
IPackageManager的AIDL結構如下:
里面涉及IIterface、IPackageManager、IPackageManager.Stub、IPackageManager.Stub.Proxy這幾類:
- IPackageManager接口繼承自IIterface.java接口。在IIterface.java接口定義了方法asBinder(),其作用是將IPackageManager轉換成IBinder對象。
- IPackageManager.Stub是IPackageManager接口的的一個內部類,Stub類實現了IBinder和IPackageManager接口。
- IPackageManager.Stub定義了asInterface(IBinder)方法;該方法將IBinder對象轉換成IPackageManager類型的對象,返回的是IPackageManager.Stub.Proxy對象
- IPackageManager.Stub類重寫了Binder類的onTransact()方法;該方法根據命令類型,處理數據傳輸。
- IPackageManager.Stub類實現了asBinder()方法,該方法直接返回IPackageManager.Stub對象。
- IPackageManager.Stub類并未實現IPackageManager實現的方法。
- IPackageManager.Stub類有一個內部類Proxy,其中Proxy類實現了IPackageManager接口
- IPackageManager.Stub類的內部類Proxy持有一個mRemote對象,該對象是對IPackageManager.Stub的引用。
- IPackageManager.Stub類的內部類Proxy實現了IPackageManager的方法,這些方法通過mRemote調用Binder中的transact()方法,最終調用IPackageManager.Stub的onTransact()方法處理。
- IPackageManager.Stub類的內部類Proxy也實現了IInterface.java中定義的asBinder方法,該方法返回的是mRemote
四、PackageMnager、IPackageManager與PackageManagerService
(一)、ApplicationPackageManager和PackageManagerService在IPackageManager的角色
在上面分析ContextImpl的getPackageManager()方法里面,我們知道
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
而在ActivityThread的靜態方法getPackageManager()里面
sPackageManager = IPackageManager.Stub.asInterface(b);
所以我們可以在ApplicationPackageManager里面的mPM其實就是 IPackageManager.Stub內部類Proxy對象。那對應的IPackageManager.Stub是什么?對了就是PackageManagerService.java。為什么是它因為如下:
public class PackageManagerService extends IPackageManager.Stub {
...
}
所以總結如下圖
所以結合上面的知識在結合PackageManager、ApplicationPackageManager和PackageManagerService總結如下:
- IPackageManager負責通信。IPackageManager接口類中定義了很多業務方法,但是由于安全等方面的考慮,Android對外(即SDK)提供的僅僅是一個子集,該子集被封裝在抽象類PackageManager中。客戶端一般通過Context的getPackageManager函數返回一個類型為PackageManager的對象,該對象的實際類型是PackageManager的子類ApplicationPackageManager。ApplicationPackageManager并沒有直接參與Binder通信,而是通過mPM成員變量指向了一個IPackageManager.Stub.Proxy類型的對象
- AIDL中的Binder服務端是PackageManagerService,因為PackageManagerService繼承自IPackageManager.Stub。由于IPackageManager.Stub類從Binder派生,所以PackageManagerService將作為服務端參與Binder通信。
- AIDL中的Binder客戶端是ApplicationPackageManager中成員變量mPM,因為mPM內部指向的是IPackageManager.Stub.Proxy
整體流程的Binder結構大致如下:
(二)、獲取Client的過程
從上面的圖中我們知道通過AIDL結束,Client通過PackageManagerService去快進程調用Server端的Stub,底層依然是依靠Binder機制進行機制,Client獲取PackageManangerService的代理對象過程:
通過一層層的封裝,Client調用PackageManagerService的過程最終是通過IPackageManager.Stub.Proxy類對象進行方法調用的
(三)、在"安裝"的角色與分工
一圖以示之,如下:
(四)、另類的理解
我們用一個類比舉例:
假設你是一個公司的商務負責人,正在和客戶商談事務,在涉及公司的具體業務的同事,你要請示你的老板,你需要給你老板打電話,交流商務談判的具體細節,這里面,你就是應用進程里面的ApplicationPackageManager,IPackageManager就是你們的通信工具——電話,你老板就是SystemServer進程里面的PackageManagerService,你的電話就是IPackageManager.Stub.Proxy,老板的電話是IPackageManager.Stub。IPackageManager其實就是一個具體業務場景下的數據交換的工具而已。
那下面我們就來簡單的介紹一下PackageManagerService
五、PackageManagerService類簡介
PackageManagerService源碼地址
這個類一共16811行,一萬多行,我對谷歌的安卓團隊也是醉了。我要想把這個類講清楚,估計至少要20W字,我就簡單說下吧,希望大家理解
(一)、PackageManagerService概述與演化史
Android 的應用管理主要是通過PackageManagerService來完成的。PackageManagerService服務負責各種APK包的安裝、卸載、優化和查詢。
PackageManagerService演化史
如下圖:
建議有件下載到電腦上查看
(二)、PackageManagerService類
PackageManagerService繼承自IPackageManager.Stub,Stub類從Binder派生,因此PackageManagerService將作為服務端參與Binder通信。
1、重要的成員支持類
- ①PackageParser:
這個類主要用于解析APK,解析其AndroidManifest.xml文件得到package的所有信息。補充一下:PackageParser.Package這個類用于容納解析出的信息。- ②Settings:
這個類表示它服務處理設置和讀取包的各種狀態,它是動態的,比如userId,shareUser、permission、signature以及origPackg相關信息。安裝 包即install package其實就從要安裝的的package中抽取信息更新Settings中的內容,特別的是Settings針對shareUser和origPackage做了特別的關照。另外,為了加速啟動速度,Settings的內容會寫入/data/system/packages.xml、packages-backup.xml和packages.list,下次啟動時會直接載入。- ②Installer:這個類協助安裝過程,更多的是將針對文件/路徑的操作放在c和cpp里面去實現,真正的工作是由install承擔的,Install只是通過named socket "installd" 連接 install,使用簡單的cmd-respond協議只會intall完成工作,在其"install"命令中可以看到,其實只是創建了/data/data/<packageName>目錄而已。
2、重要的成員變量
- final PackageInstallerService mInstallerService:
PackageInstallService實例,一個應用的安裝時間比較長,Android就是用PackageInstallerService來管理應用的安裝過程。在構造函數的最后創建。- final Installer mInstaller:
被@GuardedBy 注解標記,它是Install的實例,用于和Demon進行install交互。實際上系統上進行APK格式轉換、建立數據目錄等工作,都是install進程來完成的。- final Settings mSettings:
Setting的實例,保存一些PackageManagner動態設置信息- final ArrayMap<String, PackageParser.Package> mPackages:
是被@GuardedBy注解標記的,代表系統已經安裝的package- final private ArrayMap<String, File> mExpectingBetter:
被升級過的應用列表- final SparseArray<HashSet<String>> mSystemPermissions:系統權限的集合
- final HashMap<String, String> mSharedLibraries:當前已知的共享庫
- final boolean mOnlyCore:用于判斷是否只掃描系統庫
- final ActivityIntentResolver mActivities:所有已知的Activity用于與其對應的Intent一一對應
- final ActivityIntentResolver mReceivers:所有已知的Receiver用于與其對應的Intent一一對應
- final ServiceIntentResolver mServices:所有已知的Service用于與其對應的Intent一一對應
- final ProviderIntentResolver mProviders:所有已知的provider用于與其對應的Intent一一對應
六、ServiceManager與PackageManagerService關系
(一)、ServiceManager回顧
ServiceManager顧名思義是Service的管理,該類具有一個HashMap<String, IBinder>持有一個已經注冊的Servce,并提供相應的方法以便Framework層的調用。如入發現某個Service未注冊,并會通過ServiceManagerNative.java這個Service獲取。其中ServiceManager的UML類圖如下:
ServiceManager提供的public方法都是靜態方法,這些方法實現大同小異。這里以getService(String)方法實現為例進行說明,其代碼如下:
代碼在ServiceManager.java 49行
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
其中mRemote是一個ServiceNativeManager對象。從上述實現我們發現,getService方法在執行的過程中,可能會調用ServiceManager類中getIServiceManager()中用于創建ServieManagerNative對象,其代碼如下:
代碼在ServiceManager.java 33行
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
其中ServiceManagerNative.asInterface(XXX)方法,該方法實際返回IServiceManager對象,其實實際上一個ServiceManagerNative.Proxy對象。ServiceManagerNative.java中addService(),getService()都是native方法,最終會調用service_manager.c類中方法,關于這塊可以參考Android跨進程通信IPC之6——Binder框架
(二)、PackageManagerService注冊
在Android啟動的過程中,會啟動SystemServer進行。在SystemServer啟動的過程中,會調用PackageManagerService的main()函數來初始化一個PackageManagerService對象。其中main()實現如下:
public static PackageManagerService main(Context context, Installer installer,boolean factoryTest, boolean onlyCore) {
PackageManagerService m = new PackageManagerService(context, installer,factoryTest, onlyCore);
ServiceManager.addService("package", m);
return m;
}
上面說了半天,那PackageManagerService是何時啟動的?下面就讓我們來詳細了解下
七、總結
本片文章主要講解了PackageManager與PackageManagerService的關系,PackageManagerService事實上是一個binder(PackageManagerService繼承自IPackageManager.Stub,而IPackageManager.Stub繼承自Binder),Client端通過獲取PackageManagerService的服務代理對象IPackageManager.Stub.Proxy,Proxy和Stub都實現了IPackageManager接口,Client調用了Proxy中的接口和方法,通過Proxy中的BinderProxy對象傳遞經過Binder驅動調用服務端的Binder中的方法,即Stub中的接口實現,PackageManagerService是Stub的子類,Stub中的接口方法在子類中具體實現,如下圖:
Binder框架如下:
上一篇文章APK安裝流程詳解2——PackageManager簡介
下一篇文章 APK安裝流程詳解4——安裝中關于so庫的哪些事