[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 RemoteCallbackList m_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 |

exam-IPC_wh_AIDL.pdf
RemoteService_r0_150614.zip