안드로이드 스튜디오 백그라운드 실행 - andeuloideu seutyudio baeggeulaundeu silhaeng

Android 개발/Service, Receiver

2020. 1. 18.

폰을 사용하다가 음악을 들어보신적이 있죠.

네이버 뮤직 이나 멜론 같은 앱을 실행해서 플레이를 시킨후, 

다른앱을 사용해도 꺼지지 않고 플레이가 되는데요.

이렇게 background에서 동작하는 컴포넌트가 바로 Service입니다.

오늘은 이 Service 에 대해서 정리해보도록 하겠습니다.

Service는 UI를 가지고 있지 않기 때문에, 인터랙션이 필요한 경우에는 Activity로 연결시켜야 하구요.

쓰레드 관련해서도 주의가 필요한데요. 

디폴트로 메인쓰레드에서 동작하므로, cpu를 많이 쓰는 일을 할 때는 ,다른 쓰레드에서 작동될수 있도록 해줘야 합니다.

이 밖에도 여러가지가 있지만 아래에서 관련 요소들을 보시면서 정리해볼께요.

Service를 실행시키는 방법에는 두가지가 있는데요.

startService() 메소드 를 사용하거나, onBindService() 를 통해서 실행시키는 방법입니다.

1. StartService vs BindService

그럼, StartService와 BindeService를 비교해 보겠습니다.

StartService는 앱내의 액티비티같은 컴포넌트가 호출했을 때 실행되는데요.

백그라운데에서 한가지일을 하며, 결과를 호출했던 컴포넌트에게 보내지 않습니다.

예를들면, 다운로드라든가, 파일을 업로드하는 것들이 있습니다.

bindService는 startService와는 다르게, 자신을 호출했던 컴포넌트와 인터랙션을 주고 받을 수 있습니다.

처리한 결과를 주고받을 수 있는 건데요. 서로 다른 프로세스상에 있어도 이 처리를 할 수 있습니다.

한 서비스에  여러 컴포넌트가 붙을 수도 있어요.

startService와 관련된 메소드만 구현하거나, bindService와 관련된 메소드만 구현해서,

둘중 하나만 동작하도록 할 수 있지만, 둘다 동시에 구현해서 실행할 수 도 있습니다.

우선 startService에 대한 구현에 대해서 정리해 보도록 하겠습니다.

2. StartService 의 라이프사이클

2-1. onCreate

액티비티의 onCreate와 비슷한 역할로 보시면 될 것 같습니다. 

서비스가 처음 초기화 될때 수행되는 메소드입니다.

2-2. onStartCommand

service를 다른 컴포넌트가 호출했을 경우 수행되는 데요,

서비스가 백그라운드에서 동작되기 시작합니다.

onStartCommand()에서 리턴해줘야 하는 값이 3가지 있어서 알아둬야하는데요, 

START_NOT_STICKY는 서비스가 시스템에 의해 종료되었을때 PendingIntent가 따로 있지않다면 다시 생성시켜주지 않는 것이구요. 

START_STICKY 는 시스템에 의해 종료되어도 다시 생성시켜주는 것입니다. 

왜 sticky라고 했는지 알 것같네여요. 하지만 이것도 마지막 인텐트를 다시 전해주지는 않는다고 하네요.

미디어 플레이어에 적합한 값이구요.

START_REDELIVER_INTENT 는 시스템에 의해 종료되어도 서비스는 물론, 전달되었던 intent값까지 모두 유지시켜는 값입니다.

파일다운로드처럼 중간에 값을 잃으면 않될경우에 적합합니다.

2-3. onDestroy

서비스가 더이상 사용되지 않을 때 호출되는 메소드 입니다.

다른 컴포넌트에서 startService()로 호출할 경우 onStartCommand가 실행되구요,

stopService나 stopSelf()가 호출되면 서비스가 동작을 멈추고,

시스템이 onDestory를 호출되는 사이클이에요.

그럼 이론적인 부분들은 여기까지 정리해보고,

실제 서비스로 음악을 플레이하고, 백그라운드에서도 계속 들을 수 있도록 구현하면서 더 정리해보겠습니다.

3. StartService 구현 준비

음악을 플레이해야하니, mp3파일을 한번 준비해보겠습니다.

플레이할 mp3파일을 raw폴더에 넣어볼께요.

아래와 같이 resource directory를 생성해주시구요.

안드로이드 스튜디오 백그라운드 실행 - andeuloideu seutyudio baeggeulaundeu silhaeng

리소스타입을 raw로 선택해주면 됩니다.

이렇게 생성된 폴더에 파인더에서 파일을 찾아 복사해 줍니다.

정상적으로 하셨다면, 아래와 같은 형태로 복사됩니다.

3. UI 생성

다음으로, 서비스를 호출해서 음악을 플레이할 수 있는 버튼과 정지하는 버튼을 만들겠습니다. 

레이아웃 파일에서 아래와 같이 만들어 줍니다.

MainActivity 에서 onClickListener를 달아줍니다.

버튼을 누르면, service를 실행시켜서 음악이 백그라운드에서도 재생될 수 잇도록 해보겠습니다.

4. Service 생성

Service를 생성할때는, Activity나 Fragment를 만드는 것처럼 AndroidStudio를 이용해서 만들면 편합니다.

클릭하면 아래와 같은 화면이 나오는데요.

원하는 이름으로 바꾼다음 넘어가주면 됩니다.

참고로 Exported와 Enabled옵션이 체크되어 있는 것을 알 수 있는데요.

Exported는 자신의 앱에서만 Service를 실행시킬 수 있도록 할 것인제에 대한 옵션인데요.

false로 해 놓으면 다른 앱에서는 실행시킬 수 없습니다.

Enabled는 시스템에 의해서 객체화 시킬 수 있는지에 대한 옵션인데요.

true로 해 놓으면 시스템에 의해서 시작 될 수 있습니다.

알람앱 같은 곳에서는 사용될 수 있을 것 같습니다.

안드로이드 스튜디오 백그라운드 실행 - andeuloideu seutyudio baeggeulaundeu silhaeng

이렇게 하면, 아래 보시는 것 처럼, 이미 Manifest에도 등록을 해 줍니다.

저희가 해야할일을 덜어주네요. 하지만, Manifest등록이 필요하다는 정도는 알아야할 것 같습니다.

5. Service의 onStartCommand 구현

이제 TestousSoundService 클래스에서 onStartCommand를 구현해서,

음악을 실행할 수 있도록 하겠습니다.

intent로 true, false를 받아서 음악을 실행하거나, 정지시키기 위해 아래와 같이 구현하였습니다.

그리고, 위에서도 언급했던 return값은 START_NOT_STICKY로,

시스템에 의해 종료되면 다시 실행되지 않는 값으로 하겠습니다.

6. MainActity 에서 startService

이제 준비는 거의다 되었네요.

play버튼을 누를 경우에만 true값을 intent에 실어 보내서, 음악이 재생되도록 하고, 

그렇지 않을 경우에는 음악이 멈추도록 하겠습니다.

7. Notification 넣기

추가적으로, 실행하던 앱에서 백그라운드로 실행중에 NotificationBar에서 

실행중인 앱의 MainActivity로 진입할 수 있도록 해보겠습니다.

이 때, PendingIntent를 사용하는데요.(이 부분은 추후에 정리해 보려고 합니다.)

Notification빌더에서 setContentIntent() 메소드를 사용해서, 이 intent를 전달해주면됩니다.

위와 같이 하시면, 백그라운드 음악을 듣다가 노티피케이션을 내려서 보면 아래와 같은 화면을 보실 수 있습니다.

이상으로 Service에 대해서 정리해보았는데요.

이에 대한 업데이트는 이 글을 통해서 하도록 하겠습니다.

참고로 bindService에 대해서는 다른 글에서 다루었으니 아래 링크를 참조해 주세요.