最近項(xiàng)目中有個(gè)需求需要在PackageManagerService添加一個(gè)方法,然后進(jìn)行調(diào)用。
我們知道PackageManagerService作為系統(tǒng)的核心服務(wù),由SystemServer在系統(tǒng)啟動(dòng)時(shí)創(chuàng)建,我們先看看SystemServer是如何創(chuàng)建的:
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
原來是通過一個(gè)靜態(tài)方法創(chuàng)建的,再看看這個(gè)靜態(tài)方法:
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;
}
這個(gè)方法比較簡單,就是new一個(gè)PackageManagerService的實(shí)例,然后向ServiceManager注冊(cè)。既然注冊(cè)到ServiceManager里面,我們?cè)讷@取PackageManagerService時(shí)就不必new或者調(diào)用那個(gè)main方法,因?yàn)镻ackageManagerService在構(gòu)造函數(shù)執(zhí)行了大量邏輯。
在ServiceManager中既然有addService方法,那么就應(yīng)該有g(shù)etService方法。(整個(gè)ServiceManager代碼邏輯比較簡單,就是維護(hù)了一個(gè)HashMap,用于保存各項(xiàng)系統(tǒng)服務(wù))
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;
}
看到這里我們是不是就可以這樣獲取
(PackageManagerService)ServiceManager.getService("package")
然而在編譯時(shí)報(bào)如下錯(cuò)誤

看來是PackageManagerService所在的這個(gè)包無法訪問。
是不是在外部就無法獲取了呢。這時(shí)想到,我們經(jīng)常在Acticity中通過getPackageManager獲取一個(gè)PackageManager,而PackageManager其實(shí)就是IPackageManager的一個(gè)客戶端代理。于是,我們?nèi)タ纯磄etPackageManager是如何實(shí)現(xiàn)的。
在ContextImpl中:
@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;
}
這里調(diào)用了ActivityThread的一個(gè)也叫g(shù)etPackageManager的方法,繼續(xù)看下去:
在ActivityThread中
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;
}
這里就很清晰了,也是通過ServiceManager.getService獲取,然后通過這樣的方法IPackageManager.Stub.asInterface(b);來獲取到PackageManagerService的。
這樣就比較簡單了,我們就可以這樣獲?。?/p>
IPackageManager.Stub.asInterface(ServiceManager.getService("package")).***
類似的,我們也可以通過這種形式獲取一些其他的系統(tǒng)服務(wù),比如:
ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)).endCall();