Android 시스템 프로 세 스 간 통신(IPC)메커니즘 Binder 의 서버 와 Client 가 Service Manager 인 터 페 이 스 를 얻 는 길
10593 단어 Binder서버 와 클 라 이언 트Service관리자 인터페이스
본 고 를 읽 기 전에 독자 가 먼저 읽 기 를 바란다Service Manager 가 안 드 로 이 드 프로 세 스 간 통신(IPC)메커니즘 Binder 데 몬 이 됨한 글 에서 언급 한 참고 자료Android 프로 세 스 간 통신(IPC)메커니즘 Binder 개요 및 학습 계획이렇게 하면 본 고 에 대한 이 해 를 강화 할 수 있다.
Service Manager 는 Binder 체제 에서 데 몬 의 역할 을 하 는 동시에 Server 역할 도 하 는 것 을 알 고 있 습 니 다.그러나 일반적인 Server 와 는 다 릅 니 다.일반적인 서버 의 경우 클 라 이언 트 가 서버 의 원 격 인 터 페 이 스 를 얻 으 려 면 Service Manager 원 격 인터페이스 에서 제공 하 는 getService 인 터 페 이 스 를 통 해 얻 어야 합 니 다.이 자체 가 Binder 체 제 를 사용 하여 프로 세 스 간 통신 을 하 는 과정 입 니 다.한편,Service Manager 라 는 서버 에 있어 Client 가 Service Manager 원 격 인 터 페 이 스 를 얻 으 려 면 프로 세 스 간 통신 체 제 를 통 해 얻 을 필요 가 없습니다.Service Manager 원 격 인 터 페 이 스 는 특수 한 Binder 참조 이기 때문에 인용 핸들 은 0 일 것 입 니 다.
Service Manager 원 격 인 터 페 이 스 를 가 져 오 는 함 수 는 default ServiceManager 입 니 다.이 함 수 는 frameworks/base/include/binder/IServiceManager.h 파일 에 있 습 니 다.
sp
frameworks/base/libs/binder/IServiceManager.cpp 파일 에서 구현:
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
gDefault ServiceManager Lock 과 gDefault ServiceManager 는 전역 변수 로 프레임 워 크/base/libs/binder/static.cpp 파일 에 정 의 됩 니 다.
Mutex gDefaultServiceManagerLock;
sp<IServiceManager> gDefaultServiceManager;
이 함수 에서 알 수 있 듯 이 gDefaultServiceManager 는 단일 모드 입 니 다.defaultServiceManager 함 수 를 호출 할 때 gDefaultServiceManager 가 만 들 어 졌 으 면 바로 돌아 갑 니 다.그렇지 않 으 면 interface 를 통 해cast인 터 페 이 스 를 계속 소개 하고 있 습 니 다cast
참고 자료 인 Android 의 심오 한 Binder 메커니즘 을 참고 한 독자 들 은 이 그림 을 쉽게 이해 할 수 있 을 것 이다.이 그림 은 BpServiceManager 클래스 가 BpInterface
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
IServiceManager 클래스 는 IInterface 클래스 를 물 려 받 았 고,IInterface 클래스 와 BpRefBase 클래스 는 각각 RefBase 클래스 를 물 려 받 았 다.BpRefBase 클래스 에 멤버 변수 mRemote 가 있 습 니 다.형식 은 IBinder*이 고 실현 클래스 는 BpBinder 입 니 다.이 는 Binder 참조,참조 핸들 값 은 BpBinder 클래스 의 mHandle 멤버 변수 에 저 장 됩 니 다.BpBinder 클래스 는 IPCThreadState 클래스 를 통 해 Binder 드라이버 와 상호 작용 하고 IPCThreadState 는 구성원 변수 mProcess 를 통 해/dev/binder 장치 파일 을 엽 니 다.mProcess 구성원 변수의 유형 은 ProcessState 입 니 다.ProcessState 클래스 는 장치/dev/binder 를 열 면 mDriverFD 구성원 변수 에 파일 설명 부 호 를 열 어 나중에 사용 할 수 있 도록 합 니 다.이러한 개념 을 이해 한 후에 Service Manager 원 격 인 터 페 이 스 를 만 드 는 과정 을 계속 분석 할 수 있 습 니 다.최종 목적 은 BpServiceManager 인 스 턴 스 를 만 들 고 IServiceManager 인 터 페 이 스 를 되 돌려 주 는 것 입 니 다.Service Manager 원 격 인 터 페 이 스 를 만 드 는 것 은 주로 다음 문장 입 니 다.
gDefaultServiceManager = interface_cast
ProcessState::self()->getContextObject(NULL));
짧 아 보이 지만 현묘 한 기 회 를 숨 기 고 안 드 로 이 드 의 심오 한 Binder 체제 라 는 참고 자 료 를 읽 을 수 있 습 니 다.여기 서 간략하게 설명 하 겠 습 니 다.
먼저 ProcessState::self 함수,self 함 수 는 ProcessState 의 정적 구성원 함수 입 니 다.이 변 수 는 전체 국면 에서 유일한 ProcessState 인 스 턴 스 변 수 를 되 돌려 주 는 역할 을 합 니 다.바로 단일 모드 입 니 다.이 변 수 는 gProcess 라 고 합 니 다.gProcess 가 생 성 되 지 않 으 면 생 성 작업 을 수행 합 니 다.ProcessState 의 구조 함수 에 서 는 open 파일 조작 함 수 를 통 해 장치 파일/dev/binder 를 열 고 돌아 오 는 장치 파일 설명 자 는 구성원 변수 mDriverFD 에 존재 합 니 다.
이 어 gProcess->getContextObject 함 수 를 호출 하여 핸들 값 이 0 인 Binder 참조,즉 BpBinder 를 얻 었 습 니 다.따라서 Service Manager 원 격 인 터 페 이 스 를 만 드 는 문 구 는 다음 과 같이 간소화 할 수 있 습 니 다.
gDefaultServiceManager = interface_cast
함수 인터페이스 다시 보기cast
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
여기 인 터 페 이 스 는 IServiceManager 입 니 다.그래서 IServiceManager:asInterface 함 수 를 호출 했 습 니 다.IServiceManager::asInterface 는 DECLARE 를 통 해META_INTERFACE(ServiceManager)매크로 는 IServiceManager 클래스 에서 설명 합 니 다.framework/base/include/binder/IServiceManager.h 파일 에 있 습 니 다.DECLARE_META_INTERFACE(ServiceManager);
다음으로:
#define DECLARE_META_INTERFACE(ServiceManager) \
static const android::String16 descriptor; \
static android::sp<IServiceManager> asInterface( \
const android::sp<android::IBinder>& obj); \
virtual const android::String16& getInterfaceDescriptor() const; \
IServiceManager(); \
virtual ~IServiceManager();
IServiceManager::asInterface 의 실현 은 IMPLEMENTMETA_INTERFACE(ServiceManager,"android.os.IServiceManager")매크로 는 framework/base/libs/binder/IServiceManager.cpp 파일 에 있 습 니 다.IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
다음으로:
#define IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager") \
const android::String16 IServiceManager::descriptor("android.os.IServiceManager"); \
const android::String16& \
IServiceManager::getInterfaceDescriptor() const { \
return IServiceManager::descriptor; \
} \
android::sp<IServiceManager> IServiceManager::asInterface( \
const android::sp<android::IBinder>& obj) \
{ \
android::sp<IServiceManager> intr; \
if (obj != NULL) { \
intr = static_cast<IServiceManager*>( \
obj->queryLocalInterface( \
IServiceManager::descriptor).get()); \
if (intr == NULL) { \
intr = new BpServiceManager(obj); \
} \
} \
return intr; \
} \
IServiceManager::IServiceManager() { } \
IServiceManager::~IServiceManager() { }
이 코드 를 쓴 직원 은 마이크로소프트 에서 구 글 로 이 직 한 것 으로 추정 된다.여기 서 우 리 는 IServiceManager::asInterface 의 실현 에 관심 을 가지 고 있 습 니 다.
android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
{
android::sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}
여기 들 어 오 는 인자 obj 는 방금 만 든 new BpBinder(0)입 니 다.BpBinder 클래스 의 구성원 함수 query LocalInterface 는 기본 클래스 인 IBinder,IBinder 를 계승 합 니 다.:query LocalInterface 함 수 는 framework/base/libs/binder/Binder.cpp 파일 에 있 습 니 다.
sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor)
{
return NULL;
}
이 를 통 해 알 수 있 듯 이 IServiceManager:asInterface 함수 에서 다음 문 구 를 호출 합 니 다.intr = new BpServiceManager(obj);
즉:
intr = new BpServiceManager(new BpBinder(0));
default ServiceManager 함수 로 돌아 가면 최종 결 과 는 다음 과 같 습 니 다.
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
이렇게 해서 Service Manager 원 격 인 터 페 이 스 를 만 들 었 습 니 다.본질 적 으로 BpServiceManager 이 고 핸들 값 이 0 인 Binder 참조 가 포함 되 어 있 습 니 다.
Android 시스템 의 Binder 시스템 에서 Server 와 Client 는 이 Service Manager 원 격 인 터 페 이 스 를 받 은 후에 어떻게 사용 합 니까?
서버 에 있어 서 는 IServiceManager:addService 라 는 인 터 페 이 스 를 호출 하여 Binder 드라이버 와 상호작용 을 하 는 것 입 니 다.즉,BpServiceManager:addService 를 호출 하 는 것 입 니 다.그리고 BpServiceManager::addService 는 기본 클래스 인 BpRefBase 의 구성원 함수 reote 를 통 해 원래 만 든 BpBinder 인 스 턴 스 를 얻 고 이 어 BpBinder:transact 구성원 함 수 를 호출 합 니 다.BpBinder::transact 함수 에서 IPCThreadState::transact 구성원 함수 가 호출 됩 니 다.여기 가 최종 적 으로 Binder 드라이버 와 상호작용 하 는 곳 입 니 다.앞의 클래스 를 기억 해 보 세 요.IPCThreadState 는 PorcessState 형식의 중간 변수 mProcess 가 있 습 니 다.mProcess 는 구성원 변수 mDriverFD 가 있 습 니 다.장치 파일/dev/binder 의 파일 설명자 입 니 다.따라서 IPCThreadState 는 파일/dev/binder 의 파일 설명 자 를 간접 적 으로 가지 고 있 는 것 과 같 습 니 다.그래서...Binder 드라이버 와 상호작용 을 할 수 있 습 니 다.
Client 에 있어 서 는 IServiceManager:getService 라 는 인 터 페 이 스 를 호출 하여 Binder 드라이버 와 상호작용 을 하 는 것 입 니 다.구체 적 인 과정 에서 상기 서버 가 Service Manager 를 사용 하 는 방법 은 같 습 니 다.여 기 는 더 이상 언급 하지 않 겠 습 니 다.
IServiceManager:addService 와 IServiceManager:getService 라 는 두 함수 의 구체 적 인 실현 은 다음 두 편의 글 에서 Binder 드라이버 라 는 층 에 깊이 들 어가 상세 한 소스 코드 분석 을 하여 Binder 프로 세 스 간 통신 체 제 를 잘 이해 할 수 있 도록 하 겠 습 니 다.주목 하 시기 바 랍 니 다.
이상 은 안 드 로 이 드 바 이 더 통신 자료 에 대한 정리 입 니 다.추 후 관련 자 료 를 계속 보충 하 겠 습 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Binder.js왜냐하면 제 가 사용 하고 있 기 때 문 입 니 다 (- -!).귀속 은 루트 테이블 을 통 해 이 루어 집 니 다.표 와 각 바 인 딩 기 안의 경로 정 보 를 통 해 데 이 터 를 업데이트 합 니 다.양 방향 으...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.