exam-IPC_wh_AIDL.pdf

 

RemoteService_r0_150614.zip

 

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 참조