
안드로이드는 앱을 프로세스 단위로 분리해 안정성과 보안을 확보합니다. 대신 서로 다른 프로세스가 데이터를 주고받아야 하는 순간이 많아지는데, 이때 핵심 기반이 되는 메커니즘이 Binder IPC입니다. 프레임워크에서 보이는 서비스 바인딩, AIDL, 시스템 서비스 호출 대부분이 결국 Binder 위에서 돌아갑니다. Android Open Source Project+1
안드로이드에서 앱 간 통신이 필요한 대표 상황
다른 앱의 기능을 호출하거나, 백그라운드에서 장기 작업을 맡기거나, 공용 데이터를 공유할 때 IPC가 필요해집니다.
예시
- 다른 앱의 Activity 실행, 공유하기 같은 사용자 중심 호출
- 백그라운드 Service에 작업 위임, 상태 조회
- 연락처, 미디어 같은 공용 데이터 접근
- 시스템 서비스 WindowManager, PackageManager, Location 같은 기능 호출
이 중 시스템 서비스 호출은 거의 모두 Binder 기반으로 구현됩니다. Android Open Source Project
안드로이드 앱 간 통신 수단을 구조로 묶어보면
Intent 기반
Activity, Service, Broadcast를 통해 메시지를 전달합니다. 사용자 흐름 또는 이벤트 브로드캐스트에 적합합니다.
ContentProvider 기반
앱 간 데이터를 표준 인터페이스로 공유합니다. 내부적으로도 IPC가 필요해지고, 많은 경우 Binder가 사용됩니다.
Messenger, ResultReceiver
Handler 메시지 형태로 요청을 전달합니다. 내부는 Binder를 사용하지만 개발자는 메시지 단위로 다룹니다.
AIDL 기반
인터페이스를 정의하고, 메서드 호출 형태로 원격 호출을 만듭니다. 이 또한 binder를 통한 IPC로 동작합니다. Android Developers+1
Binder IPC를 한 문장으로 정의하면
Binder는 커널 드라이버를 통해 프로세스 간 호출을 메서드 호출처럼 보이게 만드는 안드로이드 고유 IPC입니다. AIDL 호출은 호출 정보와 인자를 버퍼에 패킹해 다른 프로세스로 전달하고, 수신 측은 binder 스레드가 이를 받아 언패킹 후 실제 구현 메서드를 실행합니다. Android Open Source Project+1
Binder의 주요 구성 요소
Client, Server 모델
클라이언트 프로세스가 원격 메서드를 호출하면, 서버 프로세스의 구현이 실행되고 결과가 반환됩니다.
Proxy와 Stub
- Proxy는 클라이언트 쪽 대리 객체로, 로컬 메서드 호출을 트랜잭션으로 바꿔 전달합니다.
- Stub은 서버 쪽 수신 객체로, 트랜잭션을 받아 인자를 풀고 실제 구현을 호출합니다.
AIDL이 이 Proxy와 Stub 코드를 자동 생성해줍니다. Android Developers+1
Parcel과 마샬링
Binder는 호출 인자와 리턴 값을 직렬화해 전달해야 합니다. AIDL은 primitive, String, Parcelable 등을 기준으로 Parcel에 담아 전달하는 방식을 사용합니다. Android Open Source Project
Binder 드라이버
프로세스 간 데이터 전달과 객체 참조 추적을 담당하는 커널 레벨 구성요소입니다. Android Open Source Project+1
Binder 트랜잭션이 실제로 흐르는 순서
- 클라이언트가 인터페이스 메서드를 호출
- Proxy가 호출 정보를 Parcel에 담아 트랜잭션으로 변환
- 커널의 binder 드라이버가 트랜잭션을 대상 프로세스로 전달
- 서버 프로세스의 binder 스레드가 요청을 수신
- Stub이 Parcel을 풀고 실제 구현 메서드를 실행
- 결과를 다시 Parcel에 담아 클라이언트로 응답 반환
이 흐름 자체가 AOSP 문서에서 설명하는 AIDL 동작 방식과 일치합니다. Android Open Source Project+1
성능과 응답성에 영향을 주는 Binder 특징
동기 호출이 기본
대부분 호출은 결과가 올 때까지 대기하는 동기 방식입니다. 메인 스레드에서 긴 원격 호출을 하면 프레임 드롭이나 ANR로 이어질 수 있습니다.
oneway 호출로 비동기화 가능
AIDL에서 oneway를 쓰면 호출 측이 바로 리턴하고, 서버는 순차 처리합니다. 다만 결과를 즉시 받을 수 없고, 흐름 제어 방식이 달라집니다.
서버 측 binder 스레드 풀
서버는 binder 전용 스레드 풀에서 요청을 처리합니다. 동시에 많은 요청이 몰리면 큐잉이 생기고 체감 지연이 커질 수 있습니다. Android Open Source Project+1
안정성과 보안을 위한 장치
호출자 식별과 권한 체크
Binder 트랜잭션은 호출자 UID, PID 같은 정보를 기반으로 접근 제어를 할 수 있습니다. 서비스는 메서드 진입 시 permission check를 수행하는 방식으로 방어합니다.
서비스 등록과 탐색의 중심
시스템 레벨에서는 서비스 매니저를 통해 서비스가 등록되고, 클라이언트는 그 핸들을 얻어 통신을 시작하는 구조를 갖습니다. Android Open Source Project+1
DeathRecipient로 장애 감지
원격 프로세스가 죽었을 때 알림을 받아 재연결하거나 상태를 정리할 수 있습니다. 이는 장기 연결 서비스에서 중요합니다.
실무에서 자주 터지는 함정 5가지
- 메인 스레드에서 원격 호출을 길게 실행
- 큰 객체를 Parcel로 과도하게 전달
- 콜백 인터페이스를 과도하게 사용해 콜백 폭주 발생
- 서비스 구현에서 긴 작업을 binder 스레드에서 직접 처리
- 예외 처리 누락으로 RemoteException 대응이 부실
정리
안드로이드 앱 간 통신은 겉으로는 Intent, Service, ContentProvider처럼 보이지만, 시스템의 깊은 곳에서는 Binder가 IPC의 중심축 역할을 합니다. AIDL은 이 Binder 호출을 개발자가 쓰기 쉬운 인터페이스 형태로 포장한 도구이며, 내부적으로는 Parcel 직렬화, Proxy와 Stub, 커널 binder 드라이버, binder 스레드 풀의 조합으로 동작합니다. Android Open Source Project+2Android Developers+2