ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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() 메서드 재정의 해야 함

     - 내용 추가 예정

     

    반응형

    댓글

Designed by Tistory.