-
[Android/Java] 서비스Android/Java 2021. 12. 14. 14:54반응형
[모든 포스팅은 개인적 공부를 위해 작성된 글입니다]
<서비스>
- 오래 실행되는 작업을 위한 것
- 화면 앞에서 실행되는 것이 아니라 화면 뒤(백그라운드)에서 실행됨
- 화면 없이 백그라운드에서 실행되는 앱의 구성 요소
- 액티비티와 마찬가지로 서비스도 앱의 구성 요소이기 때문에 시스템에서 관리하므로 Manifest에 등록해야 함
<서비스의 3가지 유형>
1. 백그라운드
- 사용자에게 보이지 않는 작업
- 앱을 종료해도 계속 수행할 수 있음
2. 바인더
- 바인딩을 위한 서비스
- 앱의 여러 구성 요소를 서비스에 바인딩하여 서비스와 상호작용 할 수 있음((ex) 액티비티와 서비스의 상호작용)
- bindService() 메서드 호출하여 사용
- 바인딩 해제되는 경우
- 서비스 소멸
3. 포그라운드
- 사용자에게 보이는 작업
- 사용자가 다른 앱을 사용중이어도 계속해서 실행됨
<서비스의 실행 원리와 역할>
- 서비스 실행 방법 : startService() 메서드 호출
- 서비스는 실행된 상태를 계속 유지하기 위해 서비스가 비정상적으로 종료(onDestroy 호출)되더라도 시스템이 자동으로 재실행
- startService() 메서드
- Intent 객체를 파라미터로 전달
- 해당 Intent 객체는 실행할 서비스에 대한 정보 담고 있음
- 시스템은 서비스를 시작시킨 후 Intent 객체를 서비스에 전달
- 서비스가 실행 중이면 startService() 메서드를 여러 번 호출해도 서비스는 이미 메모리에 만들어진 상태임
- 해당 경우에는 시스템이 onCreate() 메서드가 아니라 onStartCommand() 메서드(서비스로 전달된 Intent 객체 처리하는 메서드/서비스가 최초로 실행되는 경우에는 onCreate() 메서드 호출됨) 실행시킴
<서비스 생성>
[app -> New -> Service -> Service]
public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } }
- 서비스 생성 시 위와 같은 코드가 생성되는데 아래와 같이 서비스 수명주기 관리 위한 onCreate(), onDestroy() 메서드, Intent 객체 전달받기 위한 onStartCommand() 메서드 추가
public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); } }
<액티비티 -> 서비스 데이터 전달>
- 액티비티에서 Intent 객체 생성하여 startService()
Intent intent = new Intent(getApplicationContext(), MyService.class); intent.putExtra("Key","값"); startService(intent);
- 서비스는 시스템에 의해 자동으로 시작될 수 있기 때문에 onStartCommand() 메서드로 전달되는 Intent 객체가 null인지 검사함
<Intent 객체가 null인 경우(null값이 반환된 경우)>
- onStartCommand() 메서드가 Service.START_STICKY 반환
- Service.START_STICKY를 반환하였다는 것은 서비스가 비정상적으로 종료(onDestory() 메서드 호출)되었다는 의미이므로 시스템이 자동으로 서비스를 재시작함(자동으로 재시작하지 않도록 하고 싶다면 다른 상수 사용할 수도 있음)
@Override public int onStartCommand(Intent intent, int flags, int startId) { if(intent == null){ return Service.START_STICKY; } return super.onStartCommand(intent, flags, startId); }
<서비스 -> 액티비티 데이터 전달>
- Intent 객체 생성 후 startActivity()
- Intent에 추가해줘야 하는 Flag
- 1. FLAG_ACTIVITY_NEW_TASK
- 새로운 Task 생성하는 플래그
- 서비스는 화면이 없기 때문에 화면이 있는 액티비티 띄우려면 새로운 Task 만들어야 하기 때문
- 2. FLAG_ACTIVITY_SINGLE_TOP, FLAG_ACTIVITY_CLEAR_TOP
- 실행하는 액티비티 객체가 이미 메모리에 만들어져 있을 때 재사용하도록 함
@Override public int onStartCommand(Intent intent, int flags, int startId) { if(intent == null){ return Service.START_STICKY; } else{ Intent intent2 = new Intent(getApplicationContext(), MainActivity.class); intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP); intent2.putExtra("Key","값"); startActivity(intent2); } return super.onStartCommand(intent, flags, startId); }
- 액티비티에서 서비스 받을 때 액티비티가 메모리에 만들어져 있지 않은 상태라면 onCreate() 메서드가 호출되어, 이미 만들어져 있는 상태라면 onNewIntent()가 호출되어 Intent 객체 참조
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = getIntent(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); }
<서비스 종료>
- stopService() 메서드 호출
<바인딩>
- 서비스가 서버 역할을 하면서 액티비티와 연결될 수 있도록 만드는 것
- 바인딩을 사용하기 위해 onBind() 메서드 재정의 해야 함
- 내용 추가 예정
반응형'Android > Java' 카테고리의 다른 글
[Android/Java] 알림(Notification) (0) 2021.12.19 [Android/Java] 애플리케이션 기본 항목 (0) 2021.12.16 [Android/Java] 메모 (0) 2021.12.15 [Android/Java] 브로드캐스트 수신자(Broadcast Receiver) (0) 2021.12.15 [Android/Java] 푸시 서비스 (0) 2021.12.11