summaryrefslogtreecommitdiff
path: root/docs/html-intl/intl/ko/guide/components/bound-services.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html-intl/intl/ko/guide/components/bound-services.jd')
-rw-r--r--docs/html-intl/intl/ko/guide/components/bound-services.jd658
1 files changed, 658 insertions, 0 deletions
diff --git a/docs/html-intl/intl/ko/guide/components/bound-services.jd b/docs/html-intl/intl/ko/guide/components/bound-services.jd
new file mode 100644
index 000000000000..bf97b260a7da
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/bound-services.jd
@@ -0,0 +1,658 @@
+page.title=바인딩된 서비스
+parent.title=서비스
+parent.link=services.html
+@jd:body
+
+
+<div id="qv-wrapper">
+<ol id="qv">
+<h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#Basics">기본 정보</a></li>
+ <li><a href="#Creating">바인딩된 서비스 생성</a>
+ <ol>
+ <li><a href="#Binder">바인더 클래스 확장</a></li>
+ <li><a href="#Messenger">메신저 사용</a></li>
+ </ol>
+ </li>
+ <li><a href="#Binding">서비스에 바인딩</a></li>
+ <li><a href="#Lifecycle">바인딩된 서비스 수명 주기 관리</a></li>
+</ol>
+
+<h2>Key 클래스</h2>
+<ol>
+ <li>{@link android.app.Service}</li>
+ <li>{@link android.content.ServiceConnection}</li>
+ <li>{@link android.os.IBinder}</li>
+</ol>
+
+<h2>샘플</h2>
+<ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+ RemoteService}</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+ LocalService}</a></li>
+</ol>
+
+<h2>참고 항목</h2>
+<ol>
+ <li><a href="{@docRoot}guide/components/services.html">서비스</a></li>
+</ol>
+</div>
+
+
+<p>바인딩된 서비스란 클라이언트 서버 인터페이스 안의 서버를 말합니다. 바인딩된 서비스를 사용하면 구성 요소(활동 등)를
+서비스에 바인딩되게 하거나, 요청을 보내고 응답을 수신하며 심지어는
+프로세스간 통신(IPC)까지 수행할 수 있게 됩니다. 일반적으로 바인딩된 서비스는 다른 애플리케이션
+구성 요소를 도울 때까지만 살고 배경에서 무한히 실행되지 않습니다.</p>
+
+<p>이 문서는 다른 애플리케이션 구성 요소의
+서비스에 바인딩하는 방법을 포함하여 바인딩된 서비스를 만드는 방법을 보여줍니다. 하지만 일반적인 서비스에 관한 정보도 알아두는 것이 좋습니다.
+서비스에서 알림을 전달하는 방법이나 서비스를 전경에서 실행되도록 설정하는 방법 등 여러 가지
+추가 정보를 알아보려면 <a href="{@docRoot}guide/components/services.html">서비스</a> 문서를 참조하십시오.</p>
+
+
+<h2 id="Basics">기본 정보</h2>
+
+<p>바인딩된 서비스란 일종의 {@link android.app.Service} 클래스 구현으로,
+이를 통해 다른 애플리케이션이 이 서비스에 바인딩하여 상호 작용할 수 있도록 해주는 것입니다. 한 서비스에 대한 바인딩을 제공하려면,
+{@link android.app.Service#onBind onBind()} 콜백 메서드를 구현해야 합니다.
+이 메서드는 클라이언트가 서비스와 상호 작용하는 데 사용하는 프로그래밍 인터페이스를 정의하는 {@link android.os.IBinder} 개체를
+반환합니다.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>시작된 서비스에 바인딩</h3>
+
+<p><a href="{@docRoot}guide/components/services.html">서비스</a>
+문서에서 논의된 바와 같이, 시작되었으면서도 바인딩된 서비스를 만들 수 있습니다. 다시 말해,
+{@link android.content.Context#startService startService()}를 호출하여 서비스를 시작할 수 있으며
+이를 통해 서비스가 무한히 실행되도록 할 수 있으며, {@link
+android.content.Context#bindService bindService()}를 호출하면 클라이언트가 해당 서비스에 바인딩되도록 할 수 있다는 것입니다.
+ <p>서비스를 시작되고 바인딩되도록 허용한 다음 서비스가 시작되면
+시스템은 클라이언트가 모두 바인딩을 해제해도 서비스를 소멸시키지 <em>않습니다</em>. 대신,
+직접 서비스를 확실히 중단시켜야 합니다. 그러려면 {@link android.app.Service#stopSelf stopSelf()} 또는 {@link
+android.content.Context#stopService stopService()}를 호출하면 됩니다.</p>
+
+<p>보통은 {@link android.app.Service#onBind onBind()}
+<em>또는</em> {@link android.app.Service#onStartCommand onStartCommand()}
+중 한 가지만 구현하지만, 둘 모두 구현해야 할 때도 있습니다. 예를 들어, 음악 플레이어의 경우 서비스를 무한히 실행하면서
+바인딩도 제공하도록 허용하는 것이 유용하다는 결론을 내릴 수 있습니다. 이렇게 하면, 한 액티비티가 서비스로 하여금 음악을 재생하도록
+시작한 다음 사용자가 애플리케이션을 떠나더라도 음악을 계속 재생하도록 할 수 있습니다. 그런 다음, 사용자가 애플리케이션으로
+다시 돌아오면 이 액티비티가 서비스를 바인딩하여 재생 제어권을 다시 획득할 수 있습니다.</p>
+
+<p><a href="#Lifecycle">바인딩된 서비스 수명 주기 관리
+</a> 관련 섹션을 꼭 읽어보십시오. 시작된 서비스에 바인딩을
+추가할 때 서비스 수명 주기에 관한 자세한 정보를 얻을 수 있습니다.</p>
+</div>
+</div>
+
+<p>클라이언트가 서비스에 바인딩하려면 {@link android.content.Context#bindService
+bindService()}를 호출하면 됩니다. 이 때, 반드시 {@link
+android.content.ServiceConnection}의 구현을 제공해야 하며 이것이 서비스와의 연결을 모니터링합니다. {@link
+android.content.Context#bindService bindService()} 메서드는 값 없이 즉시 반환됩니다.
+그러나 Android 시스템이 클라이언트와 서비스 사이의
+연결을 만드는 경우, 시스템은 {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()}를 {@link
+android.content.ServiceConnection}에서 호출하여 클라이언트가 서비스와 통신하는 데 사용할 수 있도록 {@link android.os.IBinder}를
+전달하게 됩니다.</p>
+
+<p>여러 클라이언트가 한 번에 서비스에 연결될 수 있습니다. 그러나, 시스템이 서비스의
+{@link android.app.Service#onBind onBind()} 메서드를 호출하여 {@link android.os.IBinder}를 검색하는 경우는 첫 번째 클라이언트가
+바인딩되는 경우뿐입니다. 시스템은 그 후 같은 {@link android.os.IBinder}를 바인딩되는 추가
+클라이언트 모두에 전달하며 이때는 {@link android.app.Service#onBind onBind()}를 다시 호출하지 않습니다.</p>
+
+<p>마지막 클라이언트가 서비스에서 바인딩을 해제하면 시스템은 서비스를 소멸시킵니다(
+{@link android.content.Context#startService startService()}가 서비스를 시작했을 경우 제외).</p>
+
+<p>바인딩된 서비스를 구현할 때 가장 중요한 부분은
+{@link android.app.Service#onBind onBind()} 콜백 메서드가 반환하는 인터페이스를 정의하는 것입니다.
+서비스의 {@link android.os.IBinder} 인터페이스를 정의하는 방법에는 몇 가지가 있고, 다음
+섹션에서는 각 기법에 관해 논의합니다.</p>
+
+
+
+<h2 id="Creating">바인딩된 서비스 생성</h2>
+
+<p>바인딩을 제공하는 서비스를 생성할 때는 클라이언트가 서비스와 상호 작용하는 데 사용할 수 있는 프로그래밍 인터페이스를 제공하는 {@link android.os.IBinder}
+를 제공해야 합니다.
+인터페이스를 정의하는 방법은 세 가지가 있습니다.</p>
+
+<dl>
+ <dt><a href="#Binder">바인더 클래스 확장</a></dt>
+ <dd>서비스가 본인의 애플리케이션 전용이며 클라이언트와 같은 과정으로 실행되는
+경우(이런 경우가 흔함), 인터페이스를 생성할 때 {@link android.os.Binder} 클래스를
+ 확장하고 그 인스턴스를
+{@link android.app.Service#onBind onBind()}에서 반환하는 방식을 사용해야 합니다. 클라이언트가 {@link android.os.Binder}를 받으며,
+이를 사용하여 {@link android.os.Binder} 구현 또는 심지어 {@link android.app.Service}에서
+사용할 수 있는 공개 메서드에 직접 액세스할 수 있습니다.
+ <p>이것은 서비스가 본인의 애플리케이션을 위해 단순히 배경에서 작동하는 요소에 그치는 경우
+선호되는 기법입니다. 인터페이스를 생성할 때 이 방식을 사용하지 않는 유일한 이유는
+서비스를 다른 애플리케이션에서나 별도의 프로세스에 걸쳐 사용하고 있는 경우뿐입니다.</dd>
+
+ <dt><a href="#Messenger">메신저 사용</a></dt>
+ <dd>인터페이스를 여러 프로세스에 걸쳐 적용되도록 해야 하는 경우, 서비스에 대한
+인터페이스를 {@link android.os.Messenger}로 생성할 수 있습니다.
+이 방식을 사용하면 서비스가 여러 가지 유형의 {@link
+android.os.Message} 개체에 응답하는 {@link android.os.Handler}를 정의합니다. 이 {@link android.os.Handler}
+가 {@link android.os.Messenger}의 기초이며, 이를 통해 클라이언트와 함께 {@link android.os.IBinder}
+를 공유할 수 있게 되어 클라이언트가 {@link
+android.os.Message} 개체를 사용해 서비스에 명령을 보낼 수 있게 해줍니다. 이외에도, 클라이언트가 자체적으로 {@link android.os.Messenger}를
+정의하여 서비스가 메시지를 돌려보낼 수 있도록 할 수도 있습니다.
+ <p>이것이 프로세스간 통신(IPC)을 수행하는 가장 간단한 방법입니다. {@link
+android.os.Messenger}가 모든 요청을 단일 스레드에 대기하게 해서, 서비스를 스레드로부터 안전하게
+설계하지 않아도 되기 때문입니다.</p>
+ </dd>
+
+ <dt>AIDL 사용하기</dt>
+ <dd>AIDL(Android Interface Definition Language)은 개체를 운영 체제가 이해할 수 있는
+원시 데이터로 구성 해제한 다음 여러 프로세스에 걸쳐 집결하여 IPC를 수행하기 위해
+필요한 모든 작업을 수행합니다. 이전 기법은 {@link android.os.Messenger}를 사용했는데,
+사실 그 기본 구조가 AIDL을 기반으로 하고 있는 것입니다. 위에서 언급한 바와 같이 {@link android.os.Messenger}는 단일 스레드에 모든 클라이언트 요청
+대기열을 생성하므로 서비스는 한 번에 요청을 하나씩 수신합니다. 그러나,
+서비스가 동시에 여러 요청을 처리하도록 하고 싶은 경우에는 AIDL을 직접 사용해도
+됩니다. 이 경우, 서비스가 다중 스레딩을 할 수 있어야 하며 스레드로부터 안전하게 구축되었어야 합니다.
+ <p>AIDL을 직접 사용하려면
+프로그래밍 인터페이스를 정의하는 {@code .aidl} 파일을 생성해야 합니다. Android SDK 도구는
+이 파일을 사용하여 인터페이스를 구현하고 IPC를 처리하는 추상 클래스를 생성하고,
+그러면 개발자가 직접 이것을 서비스 내에서 확장하면 됩니다.</p>
+ </dd>
+</dl>
+
+ <p class="note"><strong>참고:</strong> 대부분의 애플리케이션의 경우,
+바인딩된 서비스를 생성하기 위해 AIDL를 사용해서는 <strong>안 됩니다</strong>.
+그러려면 다중 스레딩 기능이 필요할 수 있고, 따라서 더 복잡한 구현을 초래할 수 있기 때문입니다. 따라서 AIDL은
+대부분의 애플리케이션에 적합하지 않으므로 이 문서에서는 여러분의 서비스에 이를 이용하는 방법에 대해 다루지 않습니다. AIDL을 직접 사용해야 한다는 확신이 드는 경우,
+<a href="{@docRoot}guide/components/aidl.html">AIDL</a> 문서를 참조하십시오.
+</p>
+
+
+
+
+<h3 id="Binder">바인더 클래스 확장</h3>
+
+<p>서비스를 사용하는 것이 로컬 애플리케이션뿐이고 여러 프로세스에 걸쳐 작동할 필요가 없는 경우,
+나름의 {@link android.os.Binder} 클래스를 구현하여
+클라이언트로 하여금 서비스 내의 공개 메서드에 직접 액세스할 수 있도록 할 수도 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> 이것은 클라이언트와 서비스가
+같은 애플리케이션 및 프로세스에 있는 경우에만 통하며, 이 경우가 가장 보편적입니다. 이 방식이 잘 통하는 경우를 예로 들면,
+음악 애플리케이션에서 자체 서비스에 액티비티를 바인딩하여 배경에서 음악을 재생하도록 해야 하는
+경우가 있습니다.</p>
+
+<p>이렇게 설정하는 방법은 다음과 같습니다.</p>
+<ol>
+ <li>서비스에서 다음 중 한 가지에 해당하는 {@link android.os.Binder}의 인스턴스를 생성합니다.
+ <ul>
+ <li>클라이언트가 호출할 수 있는 공개 메서드 포함</li>
+ <li>클라이언트가 호출할 수 있는 공개 메서드가 있는 현재{@link android.app.Service}
+인스턴스를 반환</li>
+ <li>클라이언트가 호출할 수 있는 공개 메서드가 포함된 서비스가 호스팅하는 다른 클래스의 인스턴스를 반환
+</li>
+ </ul>
+ <li>{@link
+android.app.Service#onBind onBind()} 콜백 메서드에서 이 {@link android.os.Binder}의 인스턴스를 반환합니다.</li>
+ <li>클라이언트의 경우, {@link android.os.Binder}를 {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()}
+콜백 메서드에서 받아 제공된 메서드를 사용해 서비스를 바인딩하기 위해 호출합니다.</li>
+</ol>
+
+<p class="note"><strong>참고:</strong> 서비스와 클라이언트가 같은 애플리케이션에
+있어야 하는 것은 그래야만 클라이언트가 반환된 개체를 캐스팅하여 해당 API를 적절하게 호출할 수 있기 때문입니다. 또한
+서비스와 클라이언트는 같은 프로세스에 있어야 하기도 합니다. 이 기법에서는
+여러 프로세스에 걸친 집결 작업을 전혀 수행하지 않기 때문입니다.</p>
+
+<p>예컨대, 어떤 서비스가 클라이언트에게 {@link android.os.Binder} 구현을 통해 서비스 내의
+메서드에 액세스할 수 있도록 한다고 합시다.</p>
+
+<pre>
+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;
+ }
+ }
+
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ /** method for clients */
+ public int getRandomNumber() {
+ return mGenerator.nextInt(100);
+ }
+}
+</pre>
+
+<p>{@code LocalBinder}는 클라이언트에게 {@code LocalService}의 현재 인스턴스를 검색하기 위한 {@code getService()} 메서드
+를 제공합니다. 이렇게 하면 클라이언트가 서비스 내의 공개 메서드를 호출할 수 있습니다.
+ 클라이언트는 예컨대 서비스에서 {@code getRandomNumber()}를 호출할 수 있습니다.</p>
+
+<p>다음은 버튼을 클릭했을 때 {@code LocalService}에 바인딩되며 {@code getRandomNumber()}
+를 호출하는 액티비티를 나타낸 것입니다.</p>
+
+<pre>
+public class BindingActivity extends Activity {
+ LocalService mService;
+ boolean mBound = false;
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ &#64;Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to LocalService
+ Intent intent = new Intent(this, LocalService.class);
+ bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ &#64;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() {
+
+ &#64;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;
+ }
+
+ &#64;Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ mBound = false;
+ }
+ };
+}
+</pre>
+
+<p>위 예시는 클라이언트가
+{@link android.content.ServiceConnection} 구현과 {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} 콜백을 사용하여 서비스에 바인딩하는 방법을 보여줍니다. 다음
+섹션에서는 서비스에 바인딩하는 이러한 과정에 대해 좀 더 자세한 정보를 제공합니다.</p>
+
+<p class="note"><strong>참고:</strong> 위 예시에서는 서비스에서 분명히 바인딩을 해제하지는 않습니다.
+그러나 모든 클라이언트는 적절한 시점에 바인딩을 해제해야 합니다(액티비티가 일시 중지될 때 등).</p>
+
+<p>더 많은 샘플 코드를 보려면 <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>에서 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+LocalService.java}</a> 클래스와 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code
+LocalServiceActivities.java}</a> 클래스를 참조하십시오.</p>
+
+
+
+
+
+<h3 id="Messenger">메신저 사용</h3>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h4>AIDL과 비교</h4>
+ <p>IPC를 수행해야 할 경우, 인터페이스에 대해 {@link android.os.Messenger}를 사용하는 것이
+AIDL로 구현하는 것보다 간단합니다. 왜냐하면 {@link android.os.Messenger}는
+모든 호출을 서비스에 대기시키지만 순수한 AIDL 인터페이스는
+서비스에 동시에 요청을 전송하여 다중 스레딩을 처리해야 하기 때문입니다.</p>
+ <p>대부분의 애플리이션에서는 서비스가 다중 스레딩을 수행할 필요가 없으므로 {@link
+android.os.Messenger}를 사용하면 호출을 한 번에 하나씩 처리할 수 있습니다. 서비스가
+다중 스레딩되는 것이 중요한 경우, 인터페이스를 정의하는 데 <a href="{@docRoot}guide/components/aidl.html">AIDL</a>을 사용해야 합니다.</p>
+</div>
+</div>
+
+<p>서비스가 원격 프로세스와 통신해야 한다면 서비스에 인터페이스를 제공하는 데
+{@link android.os.Messenger}를 사용하면 됩니다. 이 기법을 사용하면
+AIDL을 쓰지 않고도 프로세스간 통신(IPC)을 수행할 수 있게 해줍니다.</p>
+
+<p>다음은 {@link android.os.Messenger} 사용 방법을 간략하게 요약한 것입니다.</p>
+
+<ul>
+ <li>서비스가 클라이언트로부터 각 호출에 대해 콜백을 받는 {@link android.os.Handler}를
+구현합니다.</li>
+ <li>{@link android.os.Handler}를 사용하여 {@link android.os.Messenger} 개체를 생성합니다
+(이것은 {@link android.os.Handler}에 대한 참조입니다).</li>
+ <li>{@link android.os.Messenger}가 {@link android.os.IBinder}를 생성하여 서비스가
+{@link android.app.Service#onBind onBind()}로부터 클라이언트에게 반환하도록 합니다.</li>
+ <li>클라이언트는 {@link android.os.IBinder}를 사용하여 {@link android.os.Messenger}
+(서비스의 {@link android.os.Handler}를 참조)를 인스턴트화하고, 이를 이용하여
+{@link android.os.Message} 개체를 서비스에 전송합니다.</li>
+ <li>서비스가 각 {@link android.os.Message}를 {@link
+android.os.Handler}로 수신합니다. 구체적으로는 {@link android.os.Handler#handleMessage
+handleMessage()} 메서드를 사용합니다.</li>
+</ul>
+
+
+<p>이렇게 하면, 클라이언트가 서비스에서 호출할 "메서드"가 없습니다. 대신 클라이언트는
+"메시지"({@link android.os.Message} 개체)를 전달하여 서비스가
+{@link android.os.Handler}로 받을 수 있도록 합니다.</p>
+
+<p>다음은 {@link android.os.Messenger} 인터페이스를 사용하는 간단한 예시 서비스입니다.</p>
+
+<pre>
+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 {
+ &#64;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.
+ */
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
+ return mMessenger.getBinder();
+ }
+}
+</pre>
+
+<p>{@link android.os.Handler}의 {@link android.os.Handler#handleMessage handleMessage()} 메서드에서
+서비스가 수신되는 {@link android.os.Message}를 받고
+{@link android.os.Message#what} 구성원에 기초하여 무엇을 할지 결정한다는 점을 눈여겨 보십시오.</p>
+
+<p>클라이언트는 서비스가 반환한 {@link
+android.os.IBinder}에 기초하여 {@link android.os.Messenger}를 생성하고 {@link
+android.os.Messenger#send send()}로 메시지를 전송하기만 하면 됩니다. 예를 들어, 다음은
+서비스에 바인딩하여 {@code MSG_SAY_HELLO} 메시지를 서비스에 전달하는 간단한 액티비티입니다.</p>
+
+<pre>
+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();
+ }
+ }
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ &#64;Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to the service
+ bindService(new Intent(this, MessengerService.class), mConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ &#64;Override
+ protected void onStop() {
+ super.onStop();
+ // Unbind from the service
+ if (mBound) {
+ unbindService(mConnection);
+ mBound = false;
+ }
+ }
+}
+</pre>
+
+<p>이 예시에는 서비스가 클라이언트에 응답하는 방식이 나타나 있지 않다는 것을 유념하십시오. 서비스가 응답하게 하려면
+ 클라이언트에도 {@link android.os.Messenger}를 생성해야 합니다.
+클라이언트가 {@link android.content.ServiceConnection#onServiceConnected
+onServiceConnected()} 콜백을 받으면 {@link android.os.Messenger#send send()}메서드의 {@link android.os.Message#replyTo} 매개변수에서 클라이언트의 {@link android.os.Messenger}를 포함하는 {@link android.os.Message}를
+서비스에 전송합니다.
+</p>
+
+<p>양방향 메시지를 제공하는 방법의 예시는 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code
+MessengerService.java}</a>(서비스) 및 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code
+MessengerServiceActivities.java}</a>(클라이언트) 예시를 참조하십시오.</p>
+
+
+
+
+
+<h2 id="Binding">서비스에 바인딩</h2>
+
+<p>애플리케이션 구성 요소(클라이언트)를 서비스에 바인딩하려면
+{@link android.content.Context#bindService bindService()}를 호출하면 됩니다. 그러면 Android
+system이 서비스의 {@link android.app.Service#onBind
+onBind()} 메서드를 호출하고, 이는 서비스와의 상호 작용을 위해 {@link android.os.IBinder}를 반환합니다.</p>
+
+<p>바인딩은 비동기식입니다. {@link android.content.Context#bindService
+bindService()}는 즉시 반환하고 클라이언트에게 {@link android.os.IBinder}를 반환하지 <em>않습니다</em>.
+ {@link android.os.IBinder}를 수신하려면 클라이언트는 {@link
+android.content.ServiceConnection}의 인스턴스를 생성하여 이를 {@link android.content.Context#bindService
+bindService()}에 전달해야 합니다. {@link android.content.ServiceConnection}에는
+{@link android.os.IBinder}를 전달하기 위해 시스템이 호출하는 콜백 메서드가 포함됩니다.</p>
+
+<p class="note"><strong>참고:</strong> 서비스에 바인딩할 수 있는 것은 액티비티, 서비스 및
+콘텐츠 제공자뿐입니다. 브로드캐스트 수신자로부터는 서비스에 바인딩할 수 <strong>없습니다</strong>.</p>
+
+<p>따라서, 클라이언트로부터 서비스에 바인딩하려면 다음과 같이 해야 합니다. </p>
+<ol>
+ <li>{@link android.content.ServiceConnection}을 구현합니다.
+ <p>이 구현으로 두 가지 콜백 메서드를 재정의해야 합니다.</p>
+ <dl>
+ <dt>{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}</dt>
+ <dd>시스템이 이것을 호출하여 서비스의
+{@link android.app.Service#onBind onBind()} 메서드가 반환한 {@link android.os.IBinder}를 전달합니다.</dd>
+ <dt>{@link android.content.ServiceConnection#onServiceDisconnected
+onServiceDisconnected()}</dt>
+ <dd>Android 시스템이 이것을 호출하는 경우는 서비스로의 연결이
+예기치 못하게 끊어졌을 때, 즉 서비스가 충돌했거나 중단되었을 때 등입니다.
+클라이언트가 바인딩을 해제한다고 이것이 호출되지는 <em>않습니다</em>.</dd>
+ </dl>
+ </li>
+ <li>{@link
+android.content.Context#bindService bindService()}를 호출하고 {@link
+android.content.ServiceConnection} 구현을 전달합니다. </li>
+ <li>시스템이 {@link android.content.ServiceConnection#onServiceConnected
+onServiceConnected()} 콜백 메서드를 호출하면, 인터페이스가 정의한 메서드를 사용하여
+서비스에 호출을 시작해도 됩니다.</li>
+ <li>서비스로부터 연결을 해제하려면 {@link
+android.content.Context#unbindService unbindService()}를 호출합니다.
+ <p>클라이언트가 소멸되면 이는 서비스에서 바인딩을 해제하게 되지만,
+서비스와 상호 작용을 마쳤을 때 또는 액티비티가 일시 중지되었을 때에는 항상 바인딩을 해제해야 합니다.
+이렇게 해야 서비스가 사용 중이 아닐 때에는 중지할 수 있습니다
+(바인딩과 바인딩 해제의 적절한 시기는 아래에서 좀 더 논의합니다).</p>
+ </li>
+</ol>
+
+<p>예를 들어, 다음 코드 조각은 위와 같이
+<a href="#Binder">바인더 클래스를 확장해서</a> 생성한 서비스와 클라이언트를 연결합니다. 그러므로 이것이 해야 하는 일은 반환된
+{@link android.os.IBinder}를 {@code LocalService} 클래스에 캐스팅하고 {@code
+LocalService} 인스턴스를 요청하는 것뿐입니다.</p>
+
+<pre>
+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;
+ }
+};
+</pre>
+
+<p>이 {@link android.content.ServiceConnection}이 있으면 클라이언트는
+이것을 {@link android.content.Context#bindService bindService()}에 전달하여 서비스에 바인딩할 수 있습니다. 예:</p>
+
+<pre>
+Intent intent = new Intent(this, LocalService.class);
+bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+</pre>
+
+<ul>
+ <li>{@link android.content.Context#bindService bindService()}의 첫 번째 매개변수는 바인딩할 서비스를 명시적으로 명명하는
+{@link android.content.Intent}입니다(인텐트는
+암시적일 수 있음).</li>
+<li>두 번째 매개변수는 {@link android.content.ServiceConnection} 개체입니다.</li>
+<li>세 번째 매개변수는 바인딩 옵션을 나타내는 플래그입니다. 서비스를 생성하기 위해 보통은 {@link
+android.content.Context#BIND_AUTO_CREATE}를 사용합니다(이미 살아 있는 상태가 아닌 경우).
+가능한 기타 값은 {@link android.content.Context#BIND_DEBUG_UNBIND}
+ 및 {@link android.content.Context#BIND_NOT_FOREGROUND}, 또는 값이 없는 경우 {@code 0}입니다.</li>
+</ul>
+
+
+<h3>추가 참고 사항</h3>
+
+<p>다음은 서비스에 바인딩하는 데 관한 몇 가지 중요한 참고 사항입니다.</p>
+<ul>
+ <li>항상 {@link android.os.DeadObjectException} 예외를 트래핑해야 합니다.
+이것은 연결이 끊어지면 발생합니다. 원격 메서드에 의해 발생하는 예외는 이것뿐입니다.</li>
+ <li>개체는 여러 프로세스에 걸쳐 감안된 참조입니다. </li>
+ <li>일반적으로, 클라이언트의 수명 주기를
+결합하고 분해하는 순간을 일치시키면서 바인딩과 바인딩 해제를 페어링해야 합니다. 예:
+ <ul>
+ <li>액티비티가 눈에 보이는 동안에만 서비스와 상호 작용해야 한다면
+{@link android.app.Activity#onStart onStart()}에는 바인딩하고 {@link
+android.app.Activity#onStop onStop()}에는 바인딩을 해제해야 합니다.</li>
+ <li>
+배경에서 중단되었을 때도 액티비티가 응답을 받게 하고 싶다면 {@link android.app.Activity#onCreate onCreate()}에는 바인딩하고
+{@link android.app.Activity#onDestroy onDestroy()} 중에는 바인딩을 해제합니다.
+이때, 사용자의 액티비티가 서비스가 실행되는 시간 전체에서(배경에서라도) 서비스를 사용한다는 것을 유념해야 합니다.
+서비스가 다른 프로세스에 있을 경우, 사용자가 프로세스의 가중치를 높이면 시스템이
+이를 중단할 가능성이 높아집니다.</li>
+ </ul>
+ <p class="note"><strong>참고:</strong> 일반적으로는, 액티비티의 {@link android.app.Activity#onResume onResume()}와 {@link
+android.app.Activity#onPause onPause()}에는 바인딩하거나 바인딩을 해제하지 <strong>말아야</strong> 합니다. 이러한 콜백은 모든 수명 주기 전환에서 발생하고
+이런 전환에서 발생하는 처리는
+최소한으로 유지해야 하기 때문입니다. 또한,
+사용자 애플리케이션의 여러 액티비티가 동일한 서비스에 바인딩되었고
+두 액티비티 사이에 전환이 있을 경우, 현재 액티비티의 바인딩이 해제된 후(일시중지 중) 다음 액티비티가 바인딩하기 전(재개 중)에
+서비스가 제거되었다가 다시 생성될 수 있습니다 (수명 주기를 조절하기 위한 이러한 액티비티 전환은
+<a href="{@docRoot}guide/components/activities.html#CoordinatingActivities">액티비티</a>
+문서에 설명되어 있습니다).</p>
+</ul>
+
+<p>더 많은 샘플 코드를 보려면 <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>의 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+RemoteService.java}</a> 클래스를 참조하십시오.</p>
+
+
+
+
+
+<h2 id="Lifecycle">바인딩된 서비스 수명 주기 관리</h2>
+
+<p>서비스가 모든 클라이언트로부터 바인딩 해제되면, Android 시스템이 이를 소멸시킵니다(다만
+{@link android.app.Service#onStartCommand onStartCommand()}와도 함께 시작된 경우는 예외).
+따라서, 서비스가 순전히 바인딩된 서비스일 경우에는 해당 서비스의 수명 주기를 관리하지 않아도 됩니다.
+클라이언트에 바인딩되었는지를 근거로 Android 시스템이 대신 관리해주기 때문입니다.</p>
+
+<p>그러나 {@link android.app.Service#onStartCommand
+onStartCommand()} 콜백 메서드를 구현하기로 선택하는 경우라면 서비스를 확실히 중지해야 합니다.
+서비스가 현재 <em>시작된 것</em>으로 간주되기 때문입니다. 이런 경우, 서비스는 클라이언트에 바인딩되었는지 여부와 관계없이
+{@link android.app.Service#stopSelf()}와 함께 스스로 중단되거나 다른 구성 요소가{@link
+android.content.Context#stopService stopService()}를 호출할 때까지 실행됩니다.
+</p>
+
+<p>또한, 서비스가 시작되고 바인딩을 허용할 경우 시스템이
+{@link android.app.Service#onUnbind onUnbind()} 메서드를 호출하면
+{@code true}를 선택적으로 반환할 수 있습니다. 다음에 클라이언트가 서비스에 바인딩할 때({@link
+android.app.Service#onBind onBind()}에 대한 호출을 수신하지 않고) {@link android.app.Service#onRebind
+onRebind()}에 대한 호출을 받을지 여부에 따라 결정됩니다. {@link android.app.Service#onRebind
+onRebind()}가 void를 반환하였지만 클라이언트가
+{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} 콜백에서 {@link android.os.IBinder}를 여전히 수신합니다.
+아래 그림 1은 이런 수명 주기의 논리를 나타냅니다.</p>
+
+
+<img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 시작되었으며 바인딩도 허용하는 서비스의 수명 주기입니다.
+</p>
+
+
+<p>시작된 서비스의 수명 주기에 관한 자세한 정보는 <a href="{@docRoot}guide/components/services.html#Lifecycle">서비스</a> 문서를 참조하십시오.</p>
+
+
+
+