AIDL과 Remote Service


AIDL(Android Interface Definition Language)은 전에 다뤄본 다른 IDL과 유사합니다. 클라이언트와 서비스가 프로세스간 통신(IPC)을 사용하여 서로 소통하는 데 동의한 프로그래밍 인터페이스를 정의할 수 있습니다. Android에서는 한 프로세스가 다른 프로세스의 메모리에 정상적으로 액세스할 수 없습니다. 따라서 객체들을 운영 체제가 이해할 수 있는 원시 유형으로 해체하고 해당 경계에 걸쳐 마샬링해야 합니다. 이 마샬링을 위해 코드를 작성하는 일은 상당히 지루한 작업인데, Android는 AIDL을 이용해 그 일을 대신 해줍니다.

마샬링: 한 객체의 메모리에서의 표현 방식을 저장 또는 전송에 적합한 다른 데이터 형식으로 변환하는 과정이다. 마샬링은 직렬화와 유사하며 한 오브젝트 여기서는 직렬화 된 오브젝트로 멀리 떨어진 오브젝트와 통신하기 위해 사용된다.

AIDL 인터페이스 정의

AIDL을 사용하여 바인드된 서비스를 생성하려면 다음 단계를 따라야 한다.

  1. aidl 파일 생성

    • 이 파일은 메서드 서명으로 프로그래밍 인터페이스를 정의한다.
  2. 인터페이스 구현

    • Android SDK 도구는 .aidl파일을 기반으로 Java 프로그래밍 언어로 인터페이스를 생성한다. 이 인터페이스는Binder를 확장하고 AIDL 인터페이스로부터 메서드를 구현하는 Stub라는 내부 추상 클래스를 가지고 있다. Stub클래스를 확장하고 메서드를 구현해야 한다.
  3. 클라이언트에게 인터페이스 노출

    • 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

+ Recent posts