티스토리 뷰
Remote Service 만들기
Remote Service 만들기.. 아! 머리 아프다. 일반적인 Local Service는 많이 짜봤는데, Remote Service는 안짜봤다. 여기서 말하는 Remote Service는 다른 APK에 있는 Service를 호출하여 쓰는 것이다. 이런게 가능한지도 몰랐다 ㅠㅜ;
우선 구현을 위해서 Remote Service를 만든다.
여기서 중요한것이 Service의 Intent-filter이다. 앞에서 말했다시피 다른 APK의 Service는 간단히 쓸수가 없다. 호출을 어떻게 할까? 그래서 나온방법이 action을 사용하는 것이다. 자세한 내용은 Remote Service를 호출하는 Caller소스에서 더 자세히 설명하겠다.
package com.example.testproject; public class TestService extends Service { private static final String TAG = "TestService"; private final IBinder mBinder = new IRemoteService.Stub() { @Override public int getStatus() throws RemoteException { Log.v(TAG, "getStatus()..."); return 11; } @Override public void setUri(Uri uri) { Log.v(TAG, "setUri()... " + uri); startBrowser(uri); } }; @Override public void onCreate() { super.onCreate(); Log.v(TAG, "onCreate()..."); } @Override public IBinder onBind(Intent intent) { Log.v(TAG, "onBind()..."); return mBinder; } private void startBrowser(Uri uri) { Log.v(TAG, "startBrowser()..."); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }
서비스 코드를 보자. 서비스코드는 별거 없다. IRemoteService.Stub를 구현하여 Binder를 만들고 서비스를 사용하는 client가 연결되면 호출되는 onBind()의 리턴으로 넘겨주면 된다. IRemoteService.aidl이라는 IPC 선언파일이 사용자가 만들면 IRemoteService.Stub가 자동으로 만들어 진다. 우리는 Stub를 Override만 하면 Caller가 IPC를 호출하연 Override 함수가 자동으로 호출이 되어진다.
package com.example.testproject; import android.net.Uri; interface IRemoteService { int getStatus(); void setUri(in Uri uri); }우리는 AIDL만 선언하면 안드로이드가 자동으로 빌드하여 우리가 쓰기 쉽게 만들어 준다. 이 얼마나 간단한가?
Service Client만들기
이제 우리가 만든 서비스를 써볼까나? 먼저 AndroidManifest.xml을 볼까?
Service Client의 AndroidManifest.xml은 별거 없다. 여기서 중요한것은 Remote Service가 com.example.testproject라고 client가 똑같을 필요가 없다는 것이다. Activity에서 Service Binding을 하지만 package명이 틀려도 된다. 다만 AIDL파일의 저장위치만 com.example.testproject로 하면 된다. AIDL의 package명이 Service의 package명과 틀리면 binding시 오류가 난다.
package com.example.testproject; import android.net.Uri; interface IRemoteService { int getStatus(); void setUri(in Uri uri); }
Service Client를 구현해 보자
package com.skt.skp.servicecall; import com.example.testproject.IRemoteService; public class MainActivity extends Activity { private static final String TAG = "ServiceCall"; IRemoteService mRemoteService = null; Uri uri = null; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mRemoteService = IRemoteService.Stub.asInterface(service); try { mRemoteService.getStatus(); mRemoteService.setUri(uri); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { Log.v(TAG, "RemoteService disconnected = " + mRemoteService.toString()); mRemoteService = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent("com.example.testproject.SERVICE"); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); Log.v(TAG, "start Service"); }
bindService시에 com.example.testproject.SERVICE Action명으로 호출을 하고 binding을 한다. 그리고 bindService시에 ServiceConnection을 넘겨주는데 우리는 ServiceConnection을 가지고 서비스가 연결되었는지 끊겼는지를 알수 있다. 바로 Service연결이 비동기 이기때문이다.
'Android > JNI, AIDL' 카테고리의 다른 글
Secure Sharing a Service between two application (0) | 2013.08.19 |
---|---|
Android Service (0) | 2013.01.21 |
[NDK] JNI 고급 (0) | 2012.12.28 |
[NDK] JNI 초급 (0) | 2012.12.27 |