반응형
안녕하세요 돼지왕왕돼지입니다.
오늘은 aidl을 이용하여 원격 서비스에 bind 하는 방법에 대해 알아보도록 하겠습니다.
- Android에서는 기본적으로 process간 memory 접근이 불가능합니다. Process간 Communication을 위해서는 운영체제가 이해할 수 있는 primitive형태로 object를 marshalling ( 분해의 개념 ) 받는 측에서 unmarshalling ( 조립의 개념 ) 해준다면 가능합니다.
오늘은 aidl을 이용하여 원격 서비스에 bind 하는 방법에 대해 알아보도록 하겠습니다.
AIDL 이 뭐고, 왜 필요해요?
- Android에서는 기본적으로 process간 memory 접근이 불가능합니다. Process간 Communication을 위해서는 운영체제가 이해할 수 있는 primitive형태로 object를 marshalling ( 분해의 개념 ) 받는 측에서 unmarshalling ( 조립의 개념 ) 해준다면 가능합니다.
- AIDL ( Android Interface Definition Language ) 가 marshalling & unmarshalling 작업을 해줍니다. (직접하려면 엄청 어렵다고 합니다.) 이 AIDL을 통해 IPC ( InterProcess Communication )이 가능해 집니다.
AIDL 사용해서 IPC 구현하는법, 즉 bind 하는 법 알려주세요.
1. .aidl 파일 생성
AIDL은 Java의 primitive type에 대해서는 import 없이 쓸 수 있습니다. String, CharSequence, List류, Map류도 import 없이 사용 할 수 있습니다. 앞에서 제시한 primitive type과 기본 object 류를 제외하고는 parameter 값으로 사용할 때, in, out, inout 을 설정해줘야 합니다. ( in 이 default 입니다 )
다음이 aidl 파일의 default format 입니다.
package [PACKAGE NAME]
import [위에 정의되지 않은 TYPE들]
interface [INTERFACE NAME]{
int [FUNCTION명]( [PARAMETERS] );
}
2. makefile에 .aidl 추가
이클립스를 사용한다면 이 단계는 pass 해도 됩니다. 다만, gen 에 aidl 에 매칭되는 java 파일이 생성되는지를 꼭 확인해야합니다.
이클립스 ADT 플러그인이 이 java 파일의 생성을 알아서 해줍니다. ( 안드로이드 tools/ 폴더에 AIDL 이라 불리는 컴파일러가 있다지요? )
만약 자체적으로 build 를 한다면, makefile 에 .aidl 을 추가해주어야 합니다.
대부분 이클립스를 사용하기 때문에 그 내용을 다루진 않겟습니다.
3. Interface method 구현.
AIDL이 만든 인터페이스 파일은 Stub 이라는 내부 추상 클래스를 가지는데, 이 녀석을 구현해주어야 합니다.
// @ Service
private final [AIDL Interface 명].Stub mBinder = new [AIDL Interface 명].Stub(){
// implementation
public [return value] [.aidl에 정의한 함수명]{
// to sth..
}
}
- RPC ( Remote Process Call )는 synchronized call ( 동기화 호출 )입니다. 따라서 해당 aidl 함수가 오랜 시간 작업 후에 return 을 한다면 main thread 에서 호출을 하면 안됩니다. Main Thread에서 호출 시 ANR 을 초래할 수 있습니다.
- AIDL 에서는 method만을 지원합니다. static field 는 지원하지 않습니다.
- AIDL function 에서 throw 하는 exception은 caller 에게 전달되지 않습니다.
4. 인터페이스를 client에게 제시하기
@ Service
// several interface can be provided
public Ibinder onBind( Intent intent ){
if ( [AIDL 인터페이스 이름1].class.getName().equals( intent.getAction() ) ){
return mBinder;
}
if ( [AIDL 인터페이스 이름2].class.getName().equals( intent.getAction() ) ){
return mSecondaryBinder;
}
}
private final [AIDL 인터페이스 이름1].Stub mBinder = new [AIDL 인터페이스 이름1] .Stub(){
// impleement.
}
private final
[AIDL 인터페이스 이름2] .Stub mSecondaryBinder = new
[AIDL 인터페이스 이름2] .Stub(){
// Implement.
}
5. IPC method 호출
5-1. .aidl 파일이 정의했던 인터페이스 타입 변수 선언
5-2. ServiceConnection 구현
5-3. ServiceConnection 구현 전달하는 Context.bindService() 호출
5-4. ServiceConnection.onServiceConnected() 에서 IBinder instance를 받는다. 여기서 asInterface( (IBinder) service )를 호출.
5-5. DeadObjectException 처리를 항상 해주며, (유일한 exception). Interface를 통해 함수를 호출한다.
5-6. 연결을 끊으려면, Context.unbindService()를 호출한다.
[AIDL 인터페이스 이름] mService;
@ServiceConnection 의 onServiceConnected callback function
public void onServiceConnected( ComponentName name, IBinder service ){
mService = [AIDL 인터페이스 이름].Stub.asInterface( service );
}
// 사용
try{
mService.[aidl function];
}
catch( DeadObjectException e ){
//...
}
이상입니다.
여러분도 이제 AIDL 을 쉽게 사용할 수 있겠죠??
반응형
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android/안드로이드] 어플리케이션 싸인하기 ( Sign Application ) - 개념 (0) | 2012.02.08 |
---|---|
[android/안드로이드] TextView 중간에 이미지 삽입하기. (4) | 2012.02.08 |
[android/안드로이드] activity chooser? activity selector? (0) | 2012.02.07 |
[android/안드로이드] ContentObserver 뭐하는 녀석인지 알아봅시다. (2) | 2012.02.07 |
[android/안드로이드] Android requires .class compatibility set to 5.0. Please fix project properties. 해결방법 (0) | 2012.02.07 |
댓글