안드로이드는 크게 2가지 native(c++) java framework 나뉘며 java framework 에서는 JNI 통해 native framework 재사용할 있다.

 

여기서 자바 프레임워크 서비스는 크게 2가지 방법으로 관리가 되는데 하나는 native 마찬가지로 context manager 이용하여 서비스를 등록하고 사용하는 방법, 번째는 Activity Manager 이용해서 서비스를 이용하는 방법이다.

 

1. 구조

기본적으로 JAVA 프레임워크의 동작도 native 매우 유사하다 IPC 통해 데이터를 주고받으며 해당 IPC부분은 native 완전 동일하다 , jni 통해서 클라이언트 서버의 java단과 native단을 연결해주는 작업이 추가된 것이다.

 

 Java Framework에서 proxy stub 보통 AIDL 통해서 자동 구현이 가능하다. 현재는 native hal 대해서도 AIDL 지원 가능한 것으로 알고있다(Android 10인가 11부터 지원 가능한 것으로 알고있음..)

다시 AIDL언어로 작성을 하면 IInterface 참조하는 해당 기능의 interface, proxy, stub 자동으로 생성되고 java framework 통신을 진행하기 위한 골격이 완성된다.

 

2. Service Manager

 

결국에 java framework에서도 bind driver 서비스를 등록하고 서비스를 find함으로써 native 마찬가지로 동작한다. 다만 native에서는 바로 context manager 호출해서 진행하지만,

Java 단에서는 바로 context manager 호출할 없기 때문에 service manager 호출하고 service manager jni 통해 native단의 context manager 호출함으로써 동작한다.

 

Service Manager Context Manager 대화를 진행하기위해 Binder Proxy 이용한다. Binder Proxy 실제적으로 JNI 통해 native 연결되는 곳으로 Service Manager RPC값을 받아서 전달한다.

 

 

Service Manager 동작을 조금 자세히 보면 위와 같다. 과정은 서비스를 등록하는 동작이다. (추가적으로 서비스를 find하는 과정은 native 마찬가지로 등록 과정과 유사하다)

Service Manager에서 서비스 등록을 위해 addService() 호출하면 BInderInternal 통해 JNI 연결을 진행하고 native Layer 존재하는 processState 연결된다.

여기서 processState native에서도 context Manager 통신을 위한 BpBinder 생성하는 역할을 담당한다. processState 통해 BpBinder 생성할 있다.

 

하지만 java framework에서 BpBinder 객체를 생성하고 접근하기 위해서는 BinderProxy라는 다른 객체가 필요하다. 때문에 다시 JNI 통해 java단으로 올라가서 BpBinder 객체에 접근이 가능한 Binder Proxy 객체를 생성하게 된다. 그리고 객체를 접근하는 곳은 ServiceManagerProxy이다. 다시 ServiceManagerProxy 객체가 생성된다.

 

이렇게 생성된 ServiecManagerProxy Service Manager에서 접근이 가능한 객체로 실제 addService 실행하면 ServiecManagerProxy에서 해당 커맨드를 받고 BpBinder JNI 통해 내려가서 Context Manager 명령을 전달한다.

 

결과적으로 BinderInternal Context Manager동작을 위한 Service Manager 초기화 과정이고 실제 addService 같이 Context Manager접근을 통한 동작은 ServiceManager Proxy 이용한다.

위에서 언급한 바와 같이 실제 Service find해서 사용하는 경우에도 Service Manager에서 ServiceManagerProxy getSerivce()함수를 호출함으로써 서비스 등록과 같은 구조로 동작한다.

 

3. Parcel

Parcel native에서 데이터 송수신 데이터를 전달하기위한 버퍼 역할을 했다. Parcel java framework service에서도 마찬가지로 buf 역할을 한다.

Java 역시 결국 통신은 IPC 통한 native영역에서 이루어지며 native 마찬가지로 parcel 이용한다. 하지만 java단까지 data 올라와야 되기 때문에 java Parcel 존재한다.

정리하면 jni 통해 Parcel(java) Parcel(native) 통신하며 실제 IPC 기존 native 마찬가지로 동작한다고 있다.

 

 

 

Ref

https://dev-ahn.tistory.com/92

[] 인사이드 안드로이드

 

+ Recent posts