APK安裝流程詳解3——PackageManager與PackageManagerService

APK安裝流程系列文章整體內容如下:

本片文章的主要內容如下:

  • 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源碼地址

IPackageManager的AIDL結構如下:


IPackageManager的結構.png

里面涉及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 {
   ...
}

代碼在PackageManagerService.java

所以總結如下圖


image.png

所以結合上面的知識在結合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結構大致如下:


image.png

(二)、獲取Client的過程

從上面的圖中我們知道通過AIDL結束,Client通過PackageManagerService去快進程調用Server端的Stub,底層依然是依靠Binder機制進行機制,Client獲取PackageManangerService的代理對象過程:

獲取Client的過程.png

通過一層層的封裝,Client調用PackageManagerService的過程最終是通過IPackageManager.Stub.Proxy類對象進行方法調用的

(三)、在"安裝"的角色與分工

一圖以示之,如下:


安裝中的角色.png

(四)、另類的理解

我們用一個類比舉例:

假設你是一個公司的商務負責人,正在和客戶商談事務,在涉及公司的具體業務的同事,你要請示你的老板,你需要給你老板打電話,交流商務談判的具體細節,這里面,你就是應用進程里面的ApplicationPackageManager,IPackageManager就是你們的通信工具——電話,你老板就是SystemServer進程里面的PackageManagerService,你的電話就是IPackageManager.Stub.Proxy,老板的電話是IPackageManager.Stub。IPackageManager其實就是一個具體業務場景下的數據交換的工具而已。

那下面我們就來簡單的介紹一下PackageManagerService

五、PackageManagerService類簡介

PackageManagerService源碼地址
這個類一共16811行,一萬多行,我對谷歌的安卓團隊也是醉了。我要想把這個類講清楚,估計至少要20W字,我就簡單說下吧,希望大家理解

(一)、PackageManagerService概述與演化史

Android 的應用管理主要是通過PackageManagerService來完成的。PackageManagerService服務負責各種APK包的安裝、卸載、優化和查詢。

PackageManagerService演化史
如下圖:


PackageManagerService演化史.png

建議有件下載到電腦上查看

(二)、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的UML類圖.png

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中的接口方法在子類中具體實現,如下圖:


總結.png

Binder框架如下:


IPackageManager的Binder框架.png

上一篇文章APK安裝流程詳解2——PackageManager簡介
下一篇文章 APK安裝流程詳解4——安裝中關于so庫的哪些事

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容