Title : Android Service and Messenger Basic
11월 2일 IPC를 위한 방법 중 브로드 캐스트 리시버에 대해 간단하게 공부했었다.
오늘은 그때 소개했던 다른 두 가지 선택지 중 하나인 Messenger에 대해 알아보도록 한다.
Android Service에 관한 내용까지 다루는 이유는 현재 수강 중인 강의의 구성에 따랐을 뿐이다.
Service 개념 위주
안드로이드의 4대 컴포넌트 중 하나인 서비스는 "장시간" 그리고 "백그라운드"에서 실행되어야 하는 작업을 수행한다.
서비스를 구현하기 위해서는 Service 클래스를 상속한 개발자 클래스를 생성하고, Manifest 파일에 service 태그를 이용해
등록해 주어야 한다. 이렇게 서비스가 준비되면 서비스 호출 측에서는 Intent 객체를 인자로 받는 startService 혹은
bindService 함수를 통해 서비스를 실행시키는데, 어떤 함수로 서비스를 호출하는지에 따라 서비스의 생명주기에 약간의
차이가 발생한다. 아래 이미지를 참고하고 추가적으로 알아보도록 하자.
startService()로 호출
해당 함수로 서비스가 최초로 실행될 경우 onCreate() -> onStartCommand() 순서로 생명주기가 동작하고, 만약
최초가 아닌 재호출될 경우에는 onStartCommand()만 호출되어 서비스 객체의 중복 생성을 방지한다.
해당 함수로 호출된 서비스를 종료해야 할 경우 stopService()로 인텐트를 발생시켜 종료하거나 서비스 내에서
직접 stopSelf() 함수를 사용하여 종료될 수 있다.
bindService()로 호출
해당 함수로 인텐트를 발생시켜, 서비스를 구동시켰을 경우 onCreate() -> onBind() 순서로 생명주기가 동작한다.
다른 생명 주기 함수들과 달리 onBind() 함수는 IBinder 타입의 리턴값을 가진다.
IBinder란 안드로이드의 IPC를 지원하기 위한 인터페이스로 서비스와 클라이언트 간 상호 작용을 지원하는
브릿지 역할을 한다. 즉, 클라이언트에서 서비스의 기능을 직접 이용하기 위해서 IBinder라는 인터페이스를 통해
통신을 하는 것이다. 클라이언트 측에서 bindService 함수를 사용할 때, 인텐트 외에도 ServiceConnection 객체 하나를
매개변수로 전달한다. ServiceConnection은 서비스 연결 상태 변경을 처리하기 위한 콜백 인터페이스로 클라이언트와
서비스가 연결되면, onServiceConnected() 함수가 콜백된다. 해당 함수가 콜백될 때 매개변수로 서비스가 리턴한
IBinder 객체를 받는 것이다. 보다 명확한 이해를 위해 Chat GPT에게 예제 코드와 설명을 요청하였다.
//서비스측 코드
public class MyService extends Service {
private final IBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this; // 서비스의 인스턴스를 반환
}
}
@Override
public IBinder onBind(Intent intent) {
return binder; // LocalBinder 객체를 반환
}
}
//클라이언트 측 코드
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
MyService.LocalBinder binder = (MyService.LocalBinder) service;
MyService myService = binder.getService(); // 서비스의 인스턴스를 얻음
// 이제 서비스의 메서드를 호출할 수 있음
}
아직 기본기가 부족해서 onServiceConnected 콜백 함수 내부에 작성된 아래 코드가 이해가 되지 않았다.
MyService.LocalBinder binder = (MyService.LocalBinder) service;
MyService 클래스는 클라이언트 프로젝트가 아닌 서비스 프로젝트에 작성된 코드인데, 어떻게 클라이언트에서
위와 같이 사용할 수 있는 지 이해가 되지 않아. 해당 부분을 다시 GPT에게 질문해 보았다.
이는 서비스 프로젝트의 Manifest에 서비스 태그로 MyService 클래스의 경로를 등록했고, 이러면 안드로이드
시스템에서 해당 서비스를 관리할 수 있게 되며, 다른 컴포넌트들이 인텐트를 발생시켜 해당 서비스에 접근할 수
있도록 해주었기 때문이라고 한다. 단, 아래 코드처럼 exported = "true" 로 인텐트 필터를 추가로 선언해 줘야 한다고 한다.
<service android:name=".MyService"
android:exported="true" />
순서대로 정리하면,
1. 클라이언트에서 bindService() 함수로 인텐트를 발생시킬 경우 서비스 측의 onBind() 함수가 실행
2. onBind() 함수는 IBinder 인터페이스를 리턴함
3. 이때 리턴되는 것은 Binder 클래스를 상속하여 만든 LocalBinder라는 개발자 클래스임
4. 리턴된 IBinder 객체는 클라이언트의 ServiceConnection 인터페이스의 onServiceConnected 콜백 함수의
매개변수로 전달되고, getService() 함수를 실행하여 LocalBinder 클래스 안에 정의된 서비스의 함수를
클라이언트에서 사용할 수 있게 된다.
인 것 같다. 추후 잘못된 정보가 포함되어있거나 새롭게 알게 되는 사실이 생긴다면 수정할 예정
개념적인 기초는 여기서 마무리하고, 금일 저녁 혹은 내일 퇴근 후 실제로 코드를 작성해 보며 실습 관련
포스팅을 작성할 계획이다.
단어 사전
[1] :
[2] :
Reference :
- 깡쌤의 안드로이드 앱 프로그래밍 with 자바 (유료 강의)
-
'2024.10~ > 일일 학습 노트' 카테고리의 다른 글
[2024-11-17] Fragment 기초 개념 다지기(with 깡쌤의 안드로이드 프로그래밍 with 자바) (0) | 2024.11.17 |
---|---|
[2024-11-04] 자바 입력 처리 방식 비교(2) (0) | 2024.11.05 |
[2024-11-04] 자바 입력 처리 방식 비교(1) (0) | 2024.11.04 |
[24.11.02] 브로드 캐스트 리시버와 인텐트 기초 개념 다지기 (0) | 2024.11.02 |
[24.10.27] 컴파일러에 대한 기본기 다지기 (0) | 2024.10.27 |