[Android] AIDL 을 이용한 Application Activity 및 Service 간 Method Call 과 Callback
Programming/Android 2015. 6. 14. 20:15
1. 알 수 있는 것들, 그리고 제공하는 것들
- Overall Message Sequence Flow between Application and Android Service
. Service 사용을 위한 Manifest 수정방법
. Android Service 로 Method Call 하는 방법 ( >> callback function 등록을 Service Method call 로 수행)
. Android Service 에서 수행하는 Callback Function 등록방법 (from service to application)
- Example Source Code
2. 설명하지 않는 내용들
- Android Service가 무엇인가?
- Applicatin과 Service 간의 통신은 어떤 원리로 가능한 것인가?
>> 위의 내용에 대해서는 더 잘 설명한 곳이 있어 그 곳의 Link로 대신합니다.
http://cafe.daum.net/_c21_/bbs_search_read?grpid=1MWA2&fldid=aAfL&datanum=114
3. Overall Message Sequence
Application Side에서 Service Binding을 위한 일련의 절차를 알 수 있습니다.
Android API 에 대한 중요한 function call 과 추상적인 절차에 대해 그렸습니다.
AIDL Interface 부는 AIDL file 에 정의된 Interface class를 선언합니다.
Service Connection 은 Application 에서 Service Component로 Method call을 하기에 앞서 Application 과 Service를 연결하는 과정입니다.
AIDL Interface 부는 Service에 Method Call을 수행하고, Service로부터 callback이 넘어오는 과정을 보여줍니다.
주) 위에서 쉽게 설명하기 위해서 Method Call이라고 표현했지만, 실제로는 IPC (Inter Process Call) 입니다.
Android에서는 이 IPC를 잘 숨겨놓았으며 이 인터페이스를 정의한 곳이 AIDL 파일입니다.
또한 부가적인 코드는Android IDE 툴에서 자동생성합니다.이와 같은 일련의 과정은 2번의 Reference Link를 참조하면 자세히 알 수 있습니다.
4. Service 등록을 위한 Manifest 추가 사항
5. Android Service 로 Callback Functio 등록 및 Callback 호출
A. AIDL 파일 및 Client 에서의 선언
- AIDLS Files
- ITimeService.aidl
package com.example.aidltest; import com.example.aidltest.ITimeServiceCallback; interface ITimeService { boolean registerTimeServiceCallback( ITimeServiceCallback callback ); boolean unregisterTimeServiceCallback( ITimeServiceCallback callback ); }
- ITimeServiceCallback.aidl
package com.example.aidltest; interface ITimeServiceCallback { oneway void onTimeChanged( String timeInfo); }
- AIDL Interface 선언
public class MainActivity extends ActionBarActivity { // AIDL Interfaces private ITimeService m_remoteTimeSvc = null; private ITimeServiceCallback m_remoteCallback = null;
B. Service connection Code
B.1 Client Application Codes
public class MainActivity extends ActionBarActivity { // 중략 ... // #1 Service Connection if (m_TimeSvcConnection == null) { m_TimeSvcConnection = new ServiceConnection () { @Override public void onServiceConnected(ComponentName name, IBinder service) { m_remoteTimeSvc = ITimeService.Stub.asInterface(service); if (m_remoteTimeSvc.registerTimeServiceCallback(m_remoteCallback) ) m_tvStatus.setText("Callback was registered... "); else m_tvStatus.setText("Registering Callback was failed... "); } @Override public void onServiceDisconnected(ComponentName name) { m_remoteTimeSvc = null; m_tvStatus.setText("Service is Disconnected ..."); } }; } // #2. Timer Callback m_remoteCallback = new ITimeServiceCallback.Stub (); // #3. Bind Service Intent intent = new Intent("com.example.service.TimeService"); bindService( intent, m_TimeSvcConnection, Context.BIND_AUTO_CREATE ); } }
B.2 Service Codes
public class TimeService extends Service { // 중략... final RemoteCallbackListm_cbLists = new RemoteCallbackList (); ITimeService.Stub m_binder = new ITimeService.Stub () { @Override public boolean registerTimeServiceCallback(ITimeServiceCallback callback) throws RemoteException { Log.i("B&U","m_cbLists.register "); m_cbLists.register(callback); launchTimeUpdatorThread(); return true; } @Override public boolean unregisterTimeServiceCallback(ITimeServiceCallback callback) throws RemoteException { m_cbLists.unregister(callback); return false; } }; @Override public IBinder onBind(Intent intent) { Log.i("B&U","onBind"); return m_binder; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } }
C. Method call to Service : Register Callback Function
C.1 Client Activity Code
public class MainActivity extends ActionBarActivity { // 중략 ... if (m_remoteTimeSvc.registerTimeServiceCallback(m_remoteCallback) ) m_tvStatus.setText("Callback was registered... "); else m_tvStatus.setText("Registering Callback was failed... "); // 중략 ... // #2. Timer Callback m_remoteCallback = new ITimeServiceCallback.Stub () { String m_TimeInfo = null; @Override public void onTimeChanged(String timeInfo) throws RemoteException { m_TimeInfo = timeInfo; Runnable updateUI = new Runnable() { @Override public void run() { m_tvTimeInfo.setText(m_TimeInfo); } }; m_tvTimeInfo.postDelayed(updateUI, 10); } // 중략 ... }
C.2 Service Code
>>> B.2 Code참조
D. Callback from Service
public class TimeService extends Service { // 중략... private void launchTimeUpdatorThread() { m_ThrdUpdateTime = new Thread("Time Updator") { @Override public void run() { while (true) { Log.i("B&U","Update Time... "); int cnt = m_cbLists.beginBroadcast(); for (int idx = 0 ; idx < cnt ; idx++ ) { ITimeServiceCallback callback = m_cbLists.getBroadcastItem(idx); //m_cbLists.getBroadcastCookie(index); long curTime = System.currentTimeMillis(); SimpleDateFormat tDateFormat = new SimpleDateFormat("yy/MM/dd hh:mm.ss"); callback.onTimeChanged(tDateFormat.format(new Date(curTime))); } m_cbLists.finishBroadcast(); Thread.sleep(1000); } } }; m_ThrdUpdateTime.start(); } // 중략... }
6. full source code
- Attached file 참조
'Programming > Android' 카테고리의 다른 글
[Android] db 에서 중복 row 열을 제거한 총 row 개수 얻기 (0) | 2015.06.18 |
---|---|
[Android] Listview 를 항상 끝으로 scroll 하기 (0) | 2015.06.18 |
[Android] syntax error don't know what to do with package (0) | 2015.06.13 |
[Android] error: unmappable character for encoding UTF-8 (0) | 2015.06.10 |
[Android] Java enum value 사용 및 참조 방법 (0) | 2015.06.03 |