본문 바로가기
Android 개발/android :: 공부

[Android Service] 안드로이드 서비스와 바인딩 개념 및 기본 예제 코드

by 독학하는 1인 개발자 2020. 5. 24.

안드로이드 개발 공부

 

Android Service

 

서비스와 바인딩

 

개념 및 기본 예제 코드

 

 

 

 

 

1. 서비스란?

 

Service는 백그라운드 작업을 위한 애플리케이션 구성 요소이다.

 

Activity와 비교하면 이해하기 쉽다.

Activity가 사용자에게 직접 보이는 화면이라면

Service는 뒤에서 수행된다.

 

예를 들어,

음악을 재생하거나, 파일 입출력을 수행하거나, 네트워크 트랜잭션을 차리할 수 있다.

전화 앱을 켜놓지 않은 상태에서도 전화를 받을 수 있는 것은

앱을 화면에서 직접 쓰고 있지 않아도

백그라운드에서 서비스가 돌아가고 있기 때문이다.

 

 

 

 

2. 서비스의 3가지 유형

 

1) 백그라운드

백그라운드는 이름 그대로 사용자에게 직접 보이지 않는 작업을 수행한다.

액티비티가 사용자에게 직접 보이는 화면이라면

서비스는 뒤에서 필요한 작업을 수행한다.

애플리케이션을 꺼도 백그라운드 서비스는 계속 수행할 수 있다.

 

2) 바인더

바인딩을 위한 서비스이다.

이름 그대로 여러 구성 요소(예를 들면 Acticity)를 서비스에 바인딩하여

서비스와 상호작용할 수 있다.

클라이언트-서버 유형과 비슷하다고 생각할 수 있다.

액티비티와 서비스는 따로 운영될 수 있지만

서로 바인딩하여 통신할 수도 있다.

bindService()를 호출하여 사용한다.

바인딩이 해제되면 해당 서비스는 소멸된다.

 

3) 포그라운드

서비스는 포그라운드로도 실행할 수 있다.

포그라운드는 이름 그대로 사용자에게 직접 보이는 작업을 수행한다.

오디오 앱을 예로 들면 트랙을 재생할 때 포그라운드 서비스를 사용한다.

포그라운드인데 왜 서비스냐? 사용자가 다른 앱을 사용중이어도 계속해서 실행되도록 하기 때문이다.

 

 

 

 

3. 서비스의 선언

 

서비스는 activity처럼 Manifest에서 선언해주어야 한다.

이때 application의 하위 요소로 선언해주면 된다.

 

<manifest>

   <application>

      <service android:name=".MyService"/>

   </application>

</manifest>

 

서비스는 다른 애플리케이션과도 상호작용할 수 있는데

Manifest에서 서비스를 비공개로 선언하고 다른 애플리케이션으로부터의 액세스를 차단할 수도 있다.

 

android:exported="false"를 추가하면

서비스를 본인의 앱에서만 사용 가능하게 할 수 있다.

 

android:description 특성을 추가해서 서비스에 대한 설명을 기재할 수도 있다.

 

 

 

 

 

4. 서비스의 기본 콜백 메소드

 

1) onStartCommand()

서비스를 시작하도록 요청하는 메소드이다.

서비스를 실행하려는 곳(예를 들면 Activity)에서 startService()를 써서 호출된다.

 

이 메소드가 실행되면 서비스가 시작되고 백그라운드에서 무한히 실행될 수 있다.

서비스를 중단하는 것은 stopSelf() 또는 stopService()를 써서 호출하면 된다.

 

바인딩만 제공하고자 하는 경우에는 onStartCommand()를 구현하지 않아도 된다.

 

 

2) onBind()

다른 구성 요소와 서비스를 바인딩하려는 경우에 호출한다.

바인딩을 실행하려는 곳(예를 들면 Activity)에서 bindService()를 써서 호출된다.

 

구현을 할 때는 Interface를 제공해야 한다.

return으로 IBinder를 반환하면 된다.

 

이 메소드는 항상 구현해야 한다.

구현을 하는데 바인딩을 하지 않으면 return값으로 null을 반환하면 된다.

 

 

3) onCreate()

onStartCommand() 또는 onBind()를 호출하기 전에 호출한다.

 

onStartComannd() 또는 onBind()에서 서비스를 실행하거나 바인딩을 하고 나면

서비스가 계속해서 실행되고 있는 중이 되기 때문에

일회성으로 실행되며, 서비스가 이미 실행 중이면 onCreate()는 호출되지 않는다.

 

 

4) ondestroy()

서비스를 소멸시킬 때 호출한다.

각종 리소스를 정리하기 위해 구현해야 한다.

 

 

 

 

 

5. 서비스의 호출과 소멸

 

1) startService() 서비스 호출

한 구성 요소(예를 들면 Activity)에서

startService()를 써서 서비스를 호출하면

onStartCommand()가 호출되고

서비스가 중단되기 전까지는 서비스를 실행중인 상태로 유지한다.

 

서비스를 중단하는 방법은

stopSelf()로 스스로 중단하거나,

다른 구성 요소(예를 들면 Activity)에서 stopService()를 써서 호출할 수 있다.

 

 

2) bindService() 바인딩 호출

한 구성 요소(예를 들면 Activity)에서

bindService()를 써서 서비스를 호출하면

해당 서비스는 해당 구성 요소가 바인딩된 경우에만 실행된다.

서비스가 모든 바인딩이 해제되면 시스템에 의해 소멸된다.

 

 

3) 서비스 소멸

안드로이드 시스템이 서비스를 강제로 소멸하는 경우는,

메모리 부족으로 인해 리소스를 정리하는 경우에 국한된다.

 

서비스가 강제로 소멸할 가능성은 다음과 같다.

- 서비스가 포그라운드에서 실행되는 경우 -> 소멸 가능성 희박함

- 서비스가 바인딩된 경우 -> 소멸 가능성 적음

- 서비스가 백그라운드에서 장시간 실행 중 -> 소멸 가능성 높음

 

 

4) 서비스 소멸 후 재시작

서비스가 시스템에 의해 소멸된 경우,

서비스가 다시 시작할 여부는

onStartCommand()의 return값에 따라 달라질 수 있다.

 

onStartComman()는 3가지 반환 값을 가질 수 있다.

 

(1) START_REDELIVER_INTENT

시스템이 서비스를 중단하면 서비스를 다시 생성한다.

그리고 이 서비스에 전달된 마지막 인텐트로 onStartCommand()를 호출한다.

모든 보류 인텐트가 차례로 전달된다.

파일 다운로드와 같은 서비스에 적합하다.

 

(2) START_STICKY

시스템이 서비스를 중단하면 서비스를 다시 생성한다.

마지막 인텐트를 전달하지 않고 null 인텐트로 onStartcommand()를 호출한다.

명령을 실행하진 않지만 작업을 기다리는 미디어 플레이어와 같은 서비스에 적합하다.

 

(3) START_NOT_STICKY

시스템이 서비스를 중단하면 서비스를 재생성하지 않는다.

다시 시작하려는 경우에 적합하다.

 

 

 

 

6. 서비스 클래스 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class MyService extends Service {
 
    @Override // 서비스가 최초 생성될 때만 호출
    public void onCreate() {
    }
 
    @Override // startService()로 서비스를 시작할 때 호출
    public int onStartCommand(Intent intent, int flags, int startId) { 
 
        return START_STICKY;
    }
 
    @Override // bindService()로 바인딩을 실행할 때 호출
    public IBinder onBind(Intent intent) {
 
        return mBinder;
    }
 
    @Override // unbindService()로 바인딩을 해제할 때 호출
    public boolean onUnbind(Intent intent) {
 
        return mAllowRebind;
    }
 
    @Override // 이미 onUnbind()가 호출된 후에 bindService()로 바인딩을 실행할 때 호출
    public void onRebind(Intent intent) {
 
    }
 
    @Override // 서비스가 소멸될 때 호출
    public void onDestroy() {
 
    }
 
}
cs

 

참고로 activity 콜백 메소드와 달리,

서비스 콜백 메소드는 슈퍼클래스 구현(super.)을 호출하지 않아도 된다.

 

참고로 서비스는 onStop() 콜백이 없다. 

서비스는 중단되면 소멸되어 중단 콜백은 onDestroy()가 유일하다.

 

 

 

 

 

7. 서비스 생명 주기 (Service LifeCycle)

 

서비스는 수명 주기가 두 가지로 나누니다.

- startService()로 서비스를 실행하거나

- bindService()로 바인딩만 제공하는 경우

 

물론 두 가지가 완전히 별개는 아니다.

startService()로 시작된 서비스에 바인딩을 할 수도 있다.

onStartCommand()로 처음 시작된 서비스이더라도 onBind() 호출을 받을 수 있다.

 

 

Activity의 생명주기보다는 훨씬 단순하다.

구체적인 흐름은 다음 내용을 보자.

 

 

 

 

 

 

8. 서비스의 시작과 중단

 

1) 서비스의 시작

서비스는 다른 구성 요소(예를 들어 Activity)에서

startService()를 써서 서비스의 onStartCommand()를 호출하면서 시작된다.

호출할 때는 Intent를 전달하는데, 예를 들어 다음과 같이 호출할 수 있다.

 

startService(new Intent(getApplicationContext(), MyService.class));

 

이 호출을 서비스의 onStartcommand()에서 받는다.

 

서비스가 시작되면 이를 호출한 구성 요소와 독립적인 수명 주기를 가진다.

즉 서비스는 백그라운드에서 무한히 실행될 수 있고,

서비스를 호출한 구성 요소가 소멸되어도 계속 실행될 수 있다.

 

 

2) 서비스의 중단

서비스는 수명 주기(LifeCycle)를 직접 관리해야 한다.

즉, 시스템은 기본적으로는 서비스를 중단이나 소멸시키지 않는다.

stopSelf()로 스스로 중지하거나,

다른 구성 요소(예를 들어 Activity)에서 stopService()를 써서 소멸시킬 수 있다.

 

stopService(new Intent(getApplicationContext(), MyService.class));

 

 

 

3) 액티비티 내에서만 실행 및 중단하는 법

서비스를 액티비티가 실행중인 동안에만 작동하도록 하려면

액티비티의 onCreate()에서 서비스를 생성하고

onStart()에서 서비스스를 슬행하고

onStop()에서 서비스를 중단하면 된다.

 

 

 

 

9. 바인딩 서비스 생성

바인딩된 서비스는 bindService()를 호출하여

다른 구성 요소를 서비스에 바인딩할 수 있다.

 

바인딩된 서비스를 생성하려면 onBind() 콜백 메소드를 구현하여

서비스와의 통신을 위한 Interface를 정의하는 IBinder를 return해야 한다.

그렇게 하면 다른 구성 요소가 bindService()를 호출하여 

해당 Interface를 검색하고 서비스에 있는 메소드를 호출할 수 있다.

 

서비스는 바인딩된 구성 요소를 돕기 위해 존재하는 것이기 때문에

구성 요소가 소멸되면 시스템이 서비스도 소멸시킨다.

그래서 바인딩된 서비스는 기본적으로 직접 중단하지 않아도 된다.

 

여러 구성 요소가 한 서비스에 바인딩될 수 있다.

구성 요소는 unbindService()를 호출하여 서비스에 바인딩을 해제할 수 있고

서비스에 바인딩된 구성 요소가 하나도 남지 않게 되면

서비스가 서비스를 소멸시킨다.

 

 

 

 

 

댓글