(원문: http://developer.android.com/guide/components/bound-services.html)

(위치: Develop > API Guides > App Components > Services 
> Bound Services)

(전체 번역 글 목록으로 이동하기)


서비스 바인드하기
(Bound Services)


바인드 된 서비스는 서버-클라이언트 구조에서 서버에 해당합니다. 서비스는 액티비티와 같은 컴포넌트들이 바인드 한 후, 요청을 보내고, 응답을 받고, 프로세스간 통신(IPC)를 할 수 있도록 만들 수 있습니다. 바인드 된 서비스는 보통 다른 앱컴포넌트들에게 바인드 되어 있는 동안에만 살아있으므로, 후면(background)에서 계속 실행되는 것은 아닙니다.

본 문서에서는 바인드 되는 서비스를 만드는 방법과 다른 앱컴포넌트가 서비스를 어떻게 바인드하는지에 대해 학습할 것입니다. 서비스에 대한 전반적인 내용과 서비스에서 알림을 발송하는 방법, 그리고 서비스를 전면(foreground)에서 실행되도록 하는 방법 등은 서비스에 대하여에서 학습하실 수 있습니다.


기본 개념

바인드 되는 서비스는 Service 클래스를 상속받아 만들며, 다른 앱컴포넌트들이 그것을 바인드하여 상호작용할 수 있는 서비스를 말합니다. 서비스가 바인드 되기 위해서는 onBind() 콜백 메소드를 구현해야 합니다. 이 메소드는 클라이언트들이 서비스와 상호작용할 수 있는 인터페이스를 정의한 IBinder 객체를 리턴해야 합니다. 

클라이언트는 bindService()를 호출하여 서비스에 바인드할 수 있습니다. bindService()를 호출할 때 인자로 ServiceConnection의 구현객체를 전달하는데, 이것은 서비스와의 연결상태를 모니터링하는 역할을 합니다. bindService()를 호출하면 결과값 없이 바로 리턴되지만, 안드로이드 시스템에 의해 클라이언트와 서비스가 연결되면 ServiceConnection 구현객체의 onServiceConnected() 메소드가 호출되며, 여기에서 서비스와 통신할 수 있는 IBinder 객체를 전달 받습니다. 

여러개의 클라이언트들이 동시에 하나의 서비스를 바인드 할 수 있습니다. 하지만 시스템은 IBinder를 구하기 위해 처음에만 onBind() 콜백 메소드를 호출하며, 두번째 바인드 요청부터는 onBind()를 호출하지 않고 처음에 얻은 IBinder를 전달해 줍니다.

모든 클라이언트가 서비스에서 언바인드(unbind)되면, 시스템은 (startService()로 시작된 서비스가 아닌 경우에 한하여) 서비스를 종료합니다. 

바인드 되는 서비스를 구현할 때 가장 중요한 부분은 onBind() 콜백 메소드의 구현입니다. IBinder 인터페이스를 정의하는 방법은 몇가지 있는데, 이어지는 섹션들에서 그 각각의 방법들을 학습할 것입니다.


바인드 되는 서비스 만들기

바인드 되는 서비스를 만들기 위해서는, 클라이언트가 서비스와 상호작용할 수 있도록 해주는 IBinder 인터페이스를 서비스가 제공해줘야 합니다. 여기에 세가지 방법이 있습니다:

Binder 클래스 확장하기

내 앱 내에서만 사용하고, 같은 프로세스 내에 있는 클라이언트에게만 바인드 되는 서비스라면, onBind()에서 Binder 클래스를 확장한 객체를 리턴해주면 됩니다. 클라이언트는 그 Binder 객체를 받아서, Binder에서 구현한 public 메소드나 서비스의 public 메소드를 호출할 수 있습니다. 
만약 서비스가 내 앱만을 위한 것이라면 이 방법을 사용하는 것이 좋습니다. 만약 다른 앱이나 다른 프로세스에서 서비스를 사용하려고 한다면, 이 방법을 사용하면 안됩니다.

Messenger 사용하기

서로 다른 프로세스간에 통신을 해야하는 상황이라면, Messenger를 이용하여 서비스를 위한 인터페이스를 만들 수 있습니다. 이 방법에 따르면, 서비스는 몇가지 종류의 Messenger 객체에 응답하는 Handler를 정의합니다. 이 Handler 안에서 Messenger는 클라이언트와 IBinder 객체를 공유하고, 클라이언트가 Message 객체를 이용하여 서비스에게 명령을 보낼 수 있도록 해줍니다. 게다가, 클라이언트는 자신의 Messenger 객체를 정의할 수 있고, 그것을 서비스로부터 돌려받을 수 있습니다.
이 방법은 프로세스간 통신(IPC)를 하는 가장 간단한 방법입니다. 왜냐하면, Messenger는 하나의 쓰레드에서 모든 요청을 큐(queue)에 쌓아 차례대로 처리하기 때문에, 멀티쓰레드 문제(thread-safe)를 신경쓰지 않아도 되기 때문입니다.

AIDL 사용하기

AIDL (Android Interface Definition Language)은 객체들을 원시 데이터들(primitives)로 분리하는 일을 하는데, 이것은 OS가 IPC를 하기 위해 객체를 마샬링(marshall them)할 때 그 원시 데이터들을 사용하기 때문입니다. 위의 Messenger 사용하기 방법도 실제로는 AIDL에 기반하고 있습니다. 위에서 언급했듯이 Messenger는 하나의 쓰레드를 사용하기 때문에 서비스는 한번에 하나의 요청을 차례대로 처리합니다. 하지만 한번에 여러개의 요청을 동시에 처리하기를 원한다면, AIDL을 직접 사용하여 구현해야 할 것입니다. 이러한 경우, 서비스는 멀티쓰레드 문제(thread-safe)를 신경써야 합니다.
AIDL을 직접 사용하기 위해서는, 프로그래밍 인터페이스를 정의하는 파일인 .aidl 파일을 만들어야 합니다. 안드로이드 SDK 툴은 이 파일을 이용하여, 파일 안에 정의된 인터페이스를 구현하고 IPC를 다루는 추상 클래스를 하나 만들어내는데, 서비스 클래스 안에서 이것을 확장하여 실제 동작을 구현해야 합니다.

메모: 대부분의 경우, 바인드 되는 서비스를 만들기 위해 AIDL을 직접 사용하지 않는 것이 좋습니다. 왜냐하면, 멀티쓰레드 문제를 신경써야 하고, 구현하기도 더 복잡하기 때문입니다. 따라서 권장하는 방법이 아니기 때문에 본 문서에서는 AIDL의 사용방법에 대해 구체적으로 설명하지는 않겠습니다. AIDL에 대한 자세한 내용은 따로 AIDL 문서에서 학습하실 수 있습니다.


Binder 클래스 확장하기

만약 서비스가 내 앱 내에서만 사용되고 다른 프로세스에서 바인드 될 일이 없다면, 서비스를 위한 Binder 클래스를 구현하여 그 객체를 onBind()에서 리턴해주면 됩니다. 그 Binder 객체는 서비스의 public 메소드에 직접 접근할 수 있게 해줍니다.

메모: 이 방법은 클라이언트와 서비스가 같은 앱 및 같은 프로세스 내에 있을 경우에만 동작하는데, 아마도 대부분의 경우가 그러할 것입니다. 예를 들면, 후면(background)에서 음악을 재생하는 서비스와 그것을 바인드하는 액티비티로 구성된 음악앱의 경우에 이 방법을 사용할 수 있을 것입니다.

구현방법은 아래와 같습니다:

1. 서비스 안에, Binder 클래스의 구현 객체를 만듭니다.(아래 방법 중 한 가지 적용):

  • 클라이언트가 호출할 수 있는 public 메소드를 포함한 Binder 객체를 만듭니다.
  • 클라이언트가 호출할 수 있는 public 메소드를 가지고 있는 Service 객체를 리턴합니다.
  • 클라이언트가 호출할 수 있는 public 메소드를 가지고 있는, (서비스 내에 있는) 다른 객체를 리턴합니다.

2. onBind() 콜백 메소드에서 Binder 객체를 리턴해줍니다.

3. 클라이언트의 onServiceConnected()에서 Binder 객체를 받아서, 바인드 된 서비스와 통신할 수 있습니다.

메모: 서비스와 클라이언트가 같은 앱에 있어야 하는 이유는, 클라이언트가 전달받은 객체를 앱에서 구현한 Binder 클래스로 타입 캐스팅해야하기 때문입니다. 그리고 서비스와 클라이언트가 같은 프로세스에 있어야 하는 이유는, 이 방법이 객체 전달시 마샬링을 하지 않기 때문에 다른 프로세스로는 객체를 전달할 수 없기 때문입니다.

이 방법을 적용한 예제 코드는 아래와 같습니다:

public class LocalService extends Service {
   
// Binder given to clients
   
private final IBinder mBinder = new LocalBinder();
   
// Random number generator
   
private final Random mGenerator = new Random();

   
/**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */

   
public class LocalBinder extends Binder {
       
LocalService getService() {
           
// Return this instance of LocalService so clients can call public methods
           
return LocalService.this;
       
}
   
}

   
@Override
   
public IBinder onBind(Intent intent) {
       
return mBinder;
   
}

   
/** method for clients */
   
public int getRandomNumber() {
     
return mGenerator.nextInt(100);
   
}
}

LocalBinder는 클라이언트에게 서비스 객체를 주기 위해 getService() 메소드를 제공합니다. 클라이언트는 서비스 객체를 가져와서 그것의 public 메소드를 호출할 수 있습니다. 예를 들면, 클라이언트는 서비스의 getRandomNumber() 메소드를 호출할 수 있는 것입니다.

아래 예제 코드는 LocalService를 바인드하는 액티비티이며, 버튼을 클릭했을 때 getRandomNumber()를 호출하는 것을 보여줍니다:

public class BindingActivity extends Activity {
   
LocalService mService;
   
boolean mBound = false;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView
(R.layout.main);
   
}

   
@Override
   
protected void onStart() {
       
super.onStart();
       
// Bind to LocalService
       
Intent intent = new Intent(this, LocalService.class);
        bindService
(intent, mConnection, Context.BIND_AUTO_CREATE);
   
}

   
@Override
   
protected void onStop() {
       
super.onStop();
       
// Unbind from the service
       
if (mBound) {
            unbindService
(mConnection);
            mBound
= false;
       
}
   
}

   
/** Called when a button is clicked (the button in the layout file attaches to
      * this method with the android:onClick attribute) */

   
public void onButtonClick(View v) {
       
if (mBound) {
           
// Call a method from the LocalService.
           
// However, if this call were something that might hang, then this request should
           
// occur in a separate thread to avoid slowing down the activity performance.
           
int num = mService.getRandomNumber();
           
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
       
}
   
}

   
/** Defines callbacks for service binding, passed to bindService() */
   
private ServiceConnection mConnection = new ServiceConnection() {

       
@Override
       
public void onServiceConnected(ComponentName className,
               
IBinder service) {
           
// We've bound to LocalService, cast the IBinder and get LocalService instance
           
LocalBinder binder = (LocalBinder) service;
            mService
= binder.getService();
            mBound
= true;
       
}

       
@Override
       
public void onServiceDisconnected(ComponentName arg0) {
            mBound
= false;
       
}
   
};
}

위의 예제는 클라이언트가 서비스를 바인드하기 위해 ServiceConnectiononServiceConnected() 콜백 메소드를 구현하는 방법을 보여줍니다. 

이와 관련된 다른 샘플 코드는 ApiDemos 샘플앱의 LocalServiceActivities.java 파일을 참고하시기 바랍니다.


Messenger 사용하기

서비스를 다른 프로세스와 통신할 수 있도록 만들기 위해서는, 서비스를 위한 인터페이스를 제공하는 Messenger를 사용할 수 있습니다. 이 기술은 AIDL을 직접 사용하지 않고도 프로세스간 통신(IPC)을 할 수 있도록 해줍니다.

Messenger를 사용하는 방법은 아래와 같습니다:

  • 서비스는 클라이언트의 호출 발생시 콜백을 수신하는 Handler를 구현합니다.
  • 이 Handler는 Messenger 객체를 생성할 때 생성자의 인자로 사용됩니다.
  • 서비스의 onBind()에서, Messenger 객체는 IBinder 객체를 생성하여 리턴합니다.
  • 클라이언트는 전달받은 IBinder 객체를 이용하여 Messenger 객체를 생성하며, 이 Messenger 객체를 사용하여 서비스에 Message 객체를 보낼 수 있습니다.
  • 서비스는 Handler의 handleMessage()를 통해 Message 객체를 전달받습니다.

이 방법에 따르면, 서비스는 클라이언트가 직접 호출할 "메소드"를 제공해주지 않습니다. 대신에, 클라이언트는 Message 객체들을 Messanger 객체를 통해 서비스에 전달하며, 서비스는 Handler를 통해 그것들을 받습니다.

아래는 Messenger 인터페이스를 사용하는 서비스의 예제 코드입니다:

public class MessengerService extends Service {
   
/** Command to the service to display a message */
   
static final int MSG_SAY_HELLO = 1;

   
/**
     * Handler of incoming messages from clients.
     */

   
class IncomingHandler extends Handler {
       
@Override
       
public void handleMessage(Message msg) {
           
switch (msg.what) {
               
case MSG_SAY_HELLO:
                   
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                   
break;
               
default:
                   
super.handleMessage(msg);
           
}
       
}
   
}

   
/**
     * Target we publish for clients to send messages to IncomingHandler.
     */

   
final Messenger mMessenger = new Messenger(new IncomingHandler());

   
/**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */

   
@Override
   
public IBinder onBind(Intent intent) {
       
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
       
return mMessenger.getBinder();
   
}
}

위의 예제 코드에서 HandlerhandleMessage() 메소드가 클라이언트로부터 Message 객체들을 전달받는 곳이며, Message 객체의 what 멤버변수를 통해 어떤 요청인지 구분해야 한다는 것을 알아야 합니다.

클라이언트는 서비스로부터 전달받은 IBinder 객체를 이용하여 Messenger 객체를 생성하고, Messenger 객체의 send() 메소드를 호출하여 Message 객체를 전달할 수 있습니다. 아래 예제에서는 서비스를 바인드하고, MSG_SAY_HELLO 메시지를 전달하는 것을 보여줍니다:

public class ActivityMessenger extends Activity {
   
/** Messenger for communicating with the service. */
   
Messenger mService = null;

   
/** Flag indicating whether we have called bind on the service. */
   
boolean mBound;

   
/**
     * Class for interacting with the main interface of the service.
     */

   
private ServiceConnection mConnection = new ServiceConnection() {
       
public void onServiceConnected(ComponentName className, IBinder service) {
           
// This is called when the connection with the service has been
           
// established, giving us the object we can use to
           
// interact with the service.  We are communicating with the
           
// service using a Messenger, so here we get a client-side
           
// representation of that from the raw IBinder object.
            mService
= new Messenger(service);
            mBound
= true;
       
}

       
public void onServiceDisconnected(ComponentName className) {
           
// This is called when the connection with the service has been
           
// unexpectedly disconnected -- that is, its process crashed.
            mService
= null;
            mBound
= false;
       
}
   
};

   
public void sayHello(View v) {
       
if (!mBound) return;
       
// Create and send a message to the service, using a supported 'what' value
       
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
       
try {
            mService
.send(msg);
       
} catch (RemoteException e) {
            e
.printStackTrace();
       
}
   
}

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView
(R.layout.main);
   
}

   
@Override
   
protected void onStart() {
       
super.onStart();
       
// Bind to the service
        bindService
(new Intent(this, MessengerService.class), mConnection,
           
Context.BIND_AUTO_CREATE);
   
}

   
@Override
   
protected void onStop() {
       
super.onStop();
       
// Unbind from the service
       
if (mBound) {
            unbindService
(mConnection);
            mBound
= false;
       
}
   
}
}

위의 예제는 서비스가 클라이언트에게 응답하는 방법을 보여주지는 않습니다. 서비스가 클라이언트에게 응답하도록 하기 위해서는, 클라이언트에서도 서비스에서처럼 Messenger 객체를 생성할 필요가 있습니다. 그런 다음에, 클라이언트의 onServiceConnected() 콜백 메소드가 호출 되었을 때, 서비스에게 보낼 Message 객체의 replyTo 멤버변수에 클라이언트의 Messenger 객체를 담아 보내고, 서비스에서는 전달받은 Message 객체의 replyTo가 클라이언트의 Messenger 객체이므로 이것의 send() 메소드를 호출함으로써 클라이언트에게 Message를 보낼 수 있습니다. 

양방향 메시징의 샘플 코드는 ApiDemos 샘플앱의 MessengerService.java(service)와 MessengerServiceActivities.java(client)를 참고하시기 바랍니다.


서비스를 바인드하기

앱컴포넌트들(클라이언트들)은 bindService()를 호출함으로써 서비스를 바인드할 수 있습니다. bindService()가 호출되면, 안드로이드 시스템은 서비스의 onBind() 메소드를 호출하며, 여기에서 서비스와 상호작용할 수 있는 IBinder 객체를 리턴합니다. 

바인딩 작업은 비동기적으로 동작합니다. bindService()는 메소드 호출 성공여부(boolean)를 즉시 리턴해주며, 클라이언트에게 IBinder 객체를 리턴해주지 않습니다. IBinder 객체를 받기 위해서는, 클라이언트가 ServiceConnection 구현 객체를 만들어서, bindService()를 호출할 때 인자로 넘겨줘야 합니다. 시스템은 ServiceConnection의 onServiceConnected() 콜백 메소드를 통해 IBinder 객체를 전달해 줍니다.

메모: 액티비티, 서비스, 컨텐트 프로바이더만이 서비스를 바인드할 수 있으며, 브로드캐스트 리시버는 서비스를 바인드할 수 없습니다.

따라서, 클라이언트가 서비스를 바인드하기 위해서는 아래와 같이 해야합니다:

1. ServiceConnection을 구현합니다.
   아래 두개의 콜백 메소드를 구현해야 합니다.
   onServiceConnected()
       시스템은 서비스의 onBind()에서 리턴한 IBinder를 전달해주기 
       위해 이 메소드를 호출합니다.
   onServiceDisconnected()
       안드로이드 시스템은 서비스가 크래쉬 되었거나 갑자기 종료되었을
       때 이 메소드를 호출하며, 클라이언트가 언바인드 했을 때는 호출
       하지 않습니다.

2. bindService()를 호출하며, 이때 ServiceConnection 구현 객체를 
    인자로 넘깁니다.

3. 시스템에 의해 onServiceConnected()가 호출되었을 때, 전달받은
    인터페이스에 정의된 메소드들을 이용하여 서비스의 기능을 사용할
    수 있습니다. 

4. 서비스와의 연결을 끊으려면, unbindService()를 호출합니다.
    클라이언트가 종료되면 자연히 서비스와 언바인드 될 것입니다.
    그러나, 클라이언트가 더이상 서비스를 호출할 일이 없거나,
    액티비티가 정지상태가 되는 경우와 같이 서비스가 더이상 사용되지
    않을때는 언바인드 해주는 것이 좋습니다.(바인드 및 언바인드 하는 
    적절한 위치에 대해서는 좀더 아래 부분에서 학습할 것입니다.)

아래 예제 코드는 위의 Binder 클래스 확장하기에서 학습한 코드의 일부입니다. onServiceConnected()에서는 전달받은 IBinder를 이용하여 LocalService 객체를 얻어냅니다:

LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
   
// Called when the connection with the service is established
   
public void onServiceConnected(ComponentName className, IBinder service) {
       
// Because we have bound to an explicit
       
// service that is running in our own process, we can
       
// cast its IBinder to a concrete class and directly access it.
       
LocalBinder binder = (LocalBinder) service;
        mService
= binder.getService();
        mBound
= true;
   
}

   
// Called when the connection with the service disconnects unexpectedly
   
public void onServiceDisconnected(ComponentName className) {
       
Log.e(TAG, "onServiceDisconnected");
        mBound
= false;
   
}
};

클라이언트가 서비스를 바인드하기 위해 bindService()를 호출할 때, 위의 ServiceConnection 구현 객체를 인자로 넘깁니다. 예제 코드:

Intent intent = new Intent(this, LocalService.class);
bindService
(intent, mConnection, Context.BIND_AUTO_CREATE);
  • bindService()의 첫번째 인자는 바인드할 서비스를 가리키는 인텐트입니다.(명시적 인텐트 및 암묵적 인텐트 모두 사용 가능합니다.)
  • 두번째 인자는 ServiceConnection의 구현 객체입니다.
  • 세번째 인자는 바인딩 옵션 값입니다. 보통은 서비스가 생성되어 있지 않을때 자동으로 생성해 주도록 BIND_AUTO_CREATE를 전달합니다. 전달 가능한 다른 값들로는, BIND_DEBUG_UNBINDBIND_NOT_FOREGROUND, 그리고 0(옵션 없음)이 있습니다.


추가 사항들

여기에 서비스 바인딩에 대한 몇가지 중요한 사항들을 추가합니다:

  • 다른 프로세스에 있는 서비스와의 연결이 끊어졌을 때 DeadObjectException 예외가 발생할 수 있습니다. 이는 원격 메소드 호출시에만 발생할 수 있는 예외입니다.
  • 객체들은 프로세스를 가로질러 레퍼런스 카운트됩니다.
  • 바인딩과 언바인딩은 보통 짝을 이루며, 클라이언트의 생명주기와 관계가 있습니다. 예를 들면:
    • 만약 액티비티가 화면에 보여질 때만 상호작용하게 하려면, 액티비티의 onStart()에서 바인드하고, onStop()에서 언바인드하면 됩니다.
    • 만약 액티비티가 정지되어 후면(background)에 있는 상태에서도 상호작용하게 하려면, 액티비티의 onCreate()에서 바인드하고, onDestroy()에서 언바인드하면 됩니다. 하지만 이렇게 하면 액티비티가 종료될 때까지 계속 서비스를 사용하게 된다는 점에 대해 주의해야 합니다. 

메모: 액티비티의 onResume()onPause()에서 바인드 및 언바인드하는 것은 피하는 것이 좋습니다. 이것들은 액티비티의 생명주기에서 가장 자주 호출되는 콜백 메소드인데, 서비스의 바인드 및 언바인드는 가능한한 최소한으로 하는 것이 좋기 때문입니다. 만약 여러개의 액티비티가 하나의 서비스를 바인드하고 있는 상황에서, stopped 상태에 있던 액티비티가 현재 화면에 보여지고 있던 액티비티를 제치고 resumed 상태가 되는 경우를 예로 들어보겠습니다. stopped 상태였던 액티비티가 resumed 상태로 되면서 서비스를 바인드하기 전에, 현재의 액티비티가 paused 상태로 되면서 언바인드 한다면, 서비스는 종료되었다가 다시 생성될 것입니다. (액티비티의 생명주기 변화에 대한 자세한 내용은 액티비티에 대하여에서 학습하실 수 있습니다.)  


서비스를 바인드하는 방법에 대한 샘플코드는 ApiDemos 샘플앱이 RemoteService.java 파일을 참고하시기 바랍니다.


바인드 되는 서비스의 생명주기 관리하기

서비스가 모든 클라이언트들로부터 언바인드 되면, (onStartCommand()가 호출되면서 시작된 서비스가 아닌 경우에 한하여) 안드로이드 시스템은 그 서비스를 종료시킵니다. 따라서 순전히 바인드만 된 서비스라면, 서비스의 생명주기를 관리할 필요가 없습니다. 안드로이드 시스템이 서비스의 바인드 여부를 판단하여 알아서 관리해주기 때문입니다. 

하지만 다른 앱컴포넌트에서 startService()를 호출하여, 서비스의 onStartCommand()가 호출된 경우, 즉 시작된(started) 서비스의 경우에는, 명시적으로 서비스를 종료시켜줘야 합니다. 이러한 경우에는 서비스가 클라이언트들에게 바인드 되었는지 여부와 상관없이, 서비스가 자체적으로 stopSelf()를 호출하거나 다른 앱컴포넌트가 stopService()를 호출할 때까지, 서비스는 실행됩니다. 

그리고, 서비스가 시작 및 바인드 되었다가 언바인드 되면서 onUnbind()가 호출되었을때, 여기서 true를 리턴하면, 다음번에 서비스가 다시 클라이언트에게 바인드될 때 onBind()가 호출되지 않고 onRebind()가 호출됩니다. onRebind()는 결과값을 리턴하지 않는 메소드지만, 클라이언트는 onServiceConnected()에서 (기존의) IBinder객체를 전달 받습니다. 아래의 그림1은 이러한 생명주기 흐름을 나타냅니다.


그림 1. 시작되고 바인드 되는 서비스의 생명주기


시작되는(started) 서비스의 생명주기에 대한 자세한 내용은 서비스에 대하여에서 학습하실 수 있습니다.


Posted by 개발자 김태우
,