AIDL과 Remote Service
AIDL(Android Interface Definition Language)은 전에 다뤄본 다른 IDL과 유사합니다. 클라이언트와 서비스가 프로세스간 통신(IPC)을 사용하여 서로 소통하는 데 동의한 프로그래밍 인터페이스를 정의할 수 있습니다. Android에서는 한 프로세스가 다른 프로세스의 메모리에 정상적으로 액세스할 수 없습니다. 따라서 객체들을 운영 체제가 이해할 수 있는 원시 유형으로 해체하고 해당 경계에 걸쳐 마샬링해야 합니다. 이 마샬링을 위해 코드를 작성하는 일은 상당히 지루한 작업인데, Android는 AIDL을 이용해 그 일을 대신 해줍니다.
마샬링: 한 객체의 메모리에서의 표현 방식을 저장 또는 전송에 적합한 다른 데이터 형식으로 변환하는 과정이다. 마샬링은 직렬화와 유사하며 한 오브젝트 여기서는 직렬화 된 오브젝트로 멀리 떨어진 오브젝트와 통신하기 위해 사용된다.
AIDL 인터페이스 정의
AIDL을 사용하여 바인드된 서비스를 생성하려면 다음 단계를 따라야 한다.
aidl 파일 생성
- 이 파일은 메서드 서명으로 프로그래밍 인터페이스를 정의한다.
인터페이스 구현
- Android SDK 도구는
.aidl
파일을 기반으로Java
프로그래밍 언어로 인터페이스를 생성한다. 이 인터페이스는Binder
를 확장하고AIDL
인터페이스로부터 메서드를 구현하는Stub
라는 내부 추상 클래스를 가지고 있다.Stub
클래스를 확장하고 메서드를 구현해야 한다.
- Android SDK 도구는
클라이언트에게 인터페이스 노출
Service
를 구현하고onBind()
를 재정의하여Stub
클래스의 구현을 반환한다.
리모트 바인딩
- 리모트 바인딩 서비스는 다른 프로세스에서 접근하는 것을 전제로 만들어진다. 따라서 로컬에서만 사용하는 서비스라면 리모트 바인딩 서비스를 굳이 만들 필요가 없다.
생성방법
- 바인딩한 클라이언트에 제공하는 메서드를
aidl
인터페이스로 작성한 다음에 서비스에서stub
클래스의 추상 메서드를 구현해 주면된다.
aidl 인터페이스와 생성 클래스
package com.cnu.eslab.suite;
interface ITrainingService{
boolean setServiceMode(String filename);
}
이렇게하면 Android Studio
에서는 자동으로build/generated/source/aidl
디렉터리에IRemoteService.java
가 생성된다.
Service에 Stub 구현
- Service에서는 추상 클래스인 Stub 구현체를 만든다.
public class RemoteService extends Service{
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
ITrainingService.Stub mBinder = new ITrainingService.Stub() {
@Override
public boolean setServiceMode(String filename) throws RemoteException {
// TODO Auto-generated method stub
ResultFileName = filename;
return true;
}
};
위와 같이 Stub
의 내부 기능을 구현하면 된다.
클라이언트에서 서비스 바인딩
Activity
에서 바인딩해서 사용해야 한다.bindService()
는 바인딩 결과를 비동기로 받기 때문에, 콜백으로 사용할 Service Connection
인스턴스를 bindService()
메서드에 파라미터로 전달한다.
리모트 서비스 바인딩
ITrainingService counterService;
@Override
pulbic void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
conn = new TrainingConnection();
}
private class TrainingConnection implements ServiceConnection {
public void onServiceConnected(ComponentName className,
IBinder boundService) {
counterService = ITrainingService.Stub.asInterface((IBinder)boundService);
}
//bind service가 연결 해지 됬을 때 실행 된다.
public void onServiceDisconnected(ComponentName className) {
counterService = null;
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
//restorePrefs();
super.onResume();
lock.disableKeyguard();
bindService(serviceIntent, conn, 0);
}
- connectionCall: ServiceConnection을 생성한다.
- Stub.asInterface() 메서드를 통해서 로컬인 경우는 Stub 인스턴스, 리모트인 경우 Proxy 인스턴스가 mIRemoteService에 대입된다.
- 연결이 끊길 때는 mIRemoteService를 null로 만든다.
- bindService()에 ServiceConnection을 전달한다.
- mIRemoteService의 메서드를 호출할 때는 먼저 null인지 체크한다.
'Computer Science > Android Application' 카테고리의 다른 글
Firebase 설정 방법 (0) | 2017.10.31 |
---|---|
Handler를 이용한 시간제한 기능 구현 (0) | 2017.08.22 |
NDK 사용 (0) | 2017.08.20 |
Preference (0) | 2017.08.20 |
Broadcast Receiver (0) | 2017.08.16 |