Android App 간 통신

최근 안드로이드 개발 중 서로 다른 어플리케이션끼리 통신할 일이 있었다. 구글에 따르면 AIDL 방식과 Messenger 방식이 있는데, Messenger 방식을 추천하였다. AIDL 방식은 많이 복잡하다 하여 Messenger 방식을 선택하여 개발을 진행하였다.

개발했던 내용을 다음과 같이 정리해본다.

A application - 메시지를 받기 위해 서비스를 띄움, B 앱으로부터 메세지를 받고 답장

B application - A 앱의 서비스와 바인드, 메세지 전송

1. MsgService

class MsgService : Service(){
    private val handler = MsgHandler()
    override fun onBind(intent:Intent) : IBinder{
        return Messenger(handler).binder
    }
}

2. MsgHandler

class MsgHandler : Handler() {
	override fun handleMessage(msg: Message) {
        super.handleMessage(msg)

        Logger.d(TAG, "Msg handler ${msg.what}")
        when(msg.what){
			//TODO : 들어온 메시지 처리
            ...
            
            //B 앱에 답장
            msg.replyTo.send(Message.obtain(null, 1))
        }
    }
}

3. MsgManager

public class MsgManager{
    ...
    public MsgManager(Context context){
        ComponentName cn = new ComponentName("바인드 하는 서비스 패키지", "바인드 하는 서비스 클래스");
        Intent intent = new Intent(); 
        intent.setComponent(cn);        
    }
    ...
}
public class MsgManager{
    private boolean isBound = false;
    ...
    private ServiceConnection conn = new ServiceConnection(){
      	@Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mService = new Messenger(iBinder);
            isBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            isBound = false;
            mService = null;
        }  
    };
    ...
}
...
    public void bindMsgService(){
        if(!isBound){
            context.bindService(intent, conn, Context.BIND_AUTO_CREATE);
            isBound = true;
        }
    }
...
    public void unBindMsgService(){
        if(isBound){
            context.unbindService(conn);
            isBound = false;
        }
    }
Messenger replyMessenger = new Messenger(new MsgReplyHandler());
...
    public void sendMsg(int msgType){
        if(isBound && mService != null){
            Message msg = Message.obtain(null, msgType);
            try {
                msg.replyTo = replyMessenger; //서비스에서 넘어온 값 처리
                mService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }