Package Manager 의 작업 절 차 를 분석 하 다.
Package Manager 의 설명 에는 다음 과 같은 말 이 있 습 니 다.
/**
* Class for retrieving various kinds of information related to the application
* packages that are currently installed on the device.
*
* You can find this class through {@link Context#getPackageManager}.
*/
그 중에서 우 리 는 크게 두 가 지 를 알 수 있다.1.역할:이런 유형 을 통 해 우 리 는 장치 에 설 치 된 응용 프로그램 패키지 와 관련 된 각종 정 보 를 얻 을 수 있다.2.생 성:Context 의 getPackageManager 함 수 를 통 해 이 대상 을 얻 을 수 있 습 니 다.그러나 Context 라 는 클래스 에 들 어가 면 실망 할 수 있 습 니 다.Context 는 추상 적 인 클래스 이기 때문에 이 함 수 를 실현 하지 못 했 습 니 다.사실은 실망 한 것 은 이것 뿐만 이 아 닙 니 다.PackageManager 류 를 볼 때 이것 도 추상 적 인 클래스 이 고 그 안의 함수 도 실현 되 지 않 았 다 는 것 을 알 게 되 었 습 니 다.다시 정리 하면 Context 류 가 실현 을 찾 지 못 하면 우 리 는 그의 하위 클래스 를 볼 수 있 습 니 다.Context 는 실현 류 가 있 습 니 다.사실은 Context 대상 을 사용 하 는 클래스 가 많 습 니 다.실제 적 으로 인용 한 것 은 모두 그의 실현 대상 입 니 다.이런 유형 은 바로 ContextImpl 입 니 다.이런 유형 에 들 어가 면 실현 을 볼 수 있 습 니 다.getPackageManager 함 수 를 직접 볼 수 있 습 니 다.
class ContextImpl extends Context {
private PackageManager mPackageManager;
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
// PackageManager pm
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
// ApplicationPackageManager
// ApplicationPackageManager ,
// ApplicationPackageManager pm
// ApplicationPackageManager
// ApplicationPackageManager PackageManager 。
// , Context getPackageManager 。
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
}
원 격 서비스의 로 컬 프 록 시 대상 을 가 져 온 후에 로 컬 프 록 시 대상 을 통 해 원 격 서비스의 함 수 를 직접 호출 할 수 있다 는 것 을 알 고 있 습 니 다.그래서 위 에서 Package Manager 서비스의 로 컬 프 록 시 대상 을 가 져 온 후에 이 대상 을 ApplicationPackage Manager 에 포 장 했 습 니 다.그러나 ApplicationPackage Manager 소스 코드 에서 도 볼 수 있 습 니 다.응용 프로그램 패키지 관리 자 를 호출 하 는 방법 은 본질 적 으로 대리 대상 을 실행 하 는 방법 입 니까?위의 주석 은 비교적 명확 하 게 말 하 니 자세히 보아 야 한다.
그렇다면 이 Package Manager 서비스의 로 컬 에이전트 대상 은 어떻게 얻 었 을 까?Activity Thread.getPackageManager()함수 원본 직접 보기:
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
// PacakgeManager IBinder 。
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;
}
우선 클 라 이언 트,서버,Service Manager 의 상호 관 계 를 알 아야 합 니 다.Service Manager 는 Binder 체제 에서 데 몬 역할 을 하 는 동시에 Server 역할 도 하지만 일반 Server 와 다 릅 니 다.일반적인 서버 의 경우 클 라 이언 트 가 서버 의 원 격 인 터 페 이 스 를 얻 으 려 면 Service Manager 원 격 인터페이스 에서 제공 하 는 getService 인 터 페 이 스 를 통 해 얻 어야 합 니 다.이 자체 가 Binder 체 제 를 사용 하여 프로 세 스 간 통신 을 하 는 과정 입 니 다.한편,Service Manager 라 는 서버 에 있어 Client 가 Service Manager 원 격 인 터 페 이 스 를 얻 으 려 면 프로 세 스 간 통신 체 제 를 통 해 얻 을 필요 가 없습니다.Service Manager 원 격 인 터 페 이 스 는 특수 한 Binder 참조 이기 때문에 인용 핸들 은 0 일 것 입 니 다.
위의 설명 을 통 해 우 리 는 ServiceManager.getService("package")가 원 격 서 비 스 를 받 으 려 면 먼저 Service Manager 원 격 인 터 페 이 스 를 얻 은 다음 에 Service Manager 원 격 인터페이스 에서 제공 하 는 getService 인 터 페 이 스 를 통 해 얻 을 수 있다 는 것 을 알 게 되 었 다.다음은 구현 코드 를 직접 보 겠 습 니 다.
public final class ServiceManager {
private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
// ServiceManager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
// ServiceManager ,
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
}
최종 적 으로 ServiceManager 원 격 인 터 페 이 스 를 통 해 getService 를 호출 하여 PackageManager 의 IBinder 대상 을 가 져 옵 니 다.위의 getPackageManager 함수 로 돌아 가 PackageManager 의 IBinder 대상 을 가 져 온 후 IPackageManager.Stub.asInterface(b)를 통 해 서비스 에이전트 대상 을 얻 습 니 다.이 어 맨 위로 돌아 가면 Package Manager 가 어떻게 얻 었 는 지 알 수 있 습 니 다.저 희 는 하위 애플 리 케 이 션 Package Manager 를 작 동 합 니 다.본질 적 으로 작 동 하 는 것 은 원 격 서비스 방법 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.