아래의 글은 BOOSTER 서포터즈로 활동했던 리미(dusdk***)님이
작성한 부스트코스 후기입니다.
여러분들의 성원에 더 노력하는 부스트코스가 되겠습니다.
감사합니다.
******************************************
1)링크: https://blog.naver.com/dusdkfla/221814518971
2)작성날짜: 20/02/18
<본문작성>
안녕하세요!
오늘 포스팅은 안드로이드 서비스에대해 알아보겠습니다.
카톡 화면이 보이지 않는 상태에서 메시지가 왔다고 알림 화면이 뜨는 경우를 볼 수 있습니다.
이것은 카톡 앱이 사용자의 눈에 보이지 않는 상태에서도 무언가 실행되고 있다는 것을 의미합니다.
화면이 없이도 데이터를 주고받는 기능을 실행하고 때로는 메시지를 받아서 처리해야 하는데 이 때 사용되는 것이 서비스입니다.
그럼 더 자세히 알아볼까요?
서비스(Service)
서비스는 화면이 없는 상태에서 실행되는 하나의 애플리케이션 구성요소입니다.
다시 말해 화면을 띄우지 않고도 필요한 기능을 실행할 수 있습니다.
화면 없이 백그라운드에서 실행되는 하나의 단위를 서비스(Service)라고 부릅니다.
서비스는 애플리케이션 구성요소이므로 프로젝트에 추가할 때 반드시 매니페스트 파일에도 추가해야 합니다.
서비스는 startService 메소드를 호출하면 시작됩니다.
Intent intent = new Intent(getApplicationContext(), MyService.class); intent.putExtra("command","show"); intent.putExtra("name", name); //서비스 실행할 땐 startActivity 아니라 startService 임! startService(intent);
MainActivity에서 인텐트 객체를 이용해 MyService에 넘겨주었습니다.
그럼 이 인텐트는 시스템으로 전달된 후 시스템에서 지정한 서비스를 만들고 실행하는 과정을 거치게 됩니다.
서비스도 onCreate와 onDestroy 메소드가 있어서 메모리에 만들어질 때와 메모리에서 없어질 때 자동으로 호출됩니다.
서비스는 항상 실행되어 있을 수 있도록 비정상 종료되는 상황이 벌어지더라도 시스템에 의해 자동으로 재시작됩니다.
서비스로의 명령 전달
서비스에선 넘겨받은 인텐트를 onStartCommand 메소드에서 처리합니다.
publicclassMyServiceextendsService{privatestatic final String TAG="MyService";publicMyService(){} @Override publicvoidonCreate(){super.onCreate(); Log.d(TAG,"onCreate() 호출됨.");}//서비스는 한번 만들어지면 계속 실행되어있기 때문에 다시 부를때마다 생성되는게 아님. 그래서 onCreate()에 intent 받는거 코드 넣으면 안됨.//onStartCommand 에 넣어야함. @Override public int onStartCommand(Intent intent, int flags, int startId){ Log.d(TAG,"onStartCommand() 호출됨.");if(intent ==null){return Service.START_STICKY;}else{processCommand(intent);}returnsuper.onStartCommand(intent, flags, startId);}privatevoidprocessCommand(Intent intent){ String command = intent.getStringExtra("command"); String name = intent.getStringExtra("name"); Log.d(TAG,"전달받은 데이터 : "+ command +", "+ name);try{ Thread.sleep(5000);}catch(Exception e){}} @Override publicvoidonDestroy(){super.onDestroy(); Log.d(TAG,"onDestroy() 호출됨.");} @Override public IBinder onBind(Intent intent){thrownewUnsupportedOperationException("Not yet implemented");}}
서비스에서 액티비티로 데이터 전달
서비스에는 화면이 없다 보니 사용자에게 무언가를 보여주고 싶다면 액티비티로 데이터를 전달한 후 액티비티에서 보여주어야 합니다.
서비스에서 액티비티로 데이터를 전달할 때는 인텐트를 사용하며 인텐트 안에 부가데이터를 넣어 보냅니다.
Intent showIntent = new Intent(getApplicationContext(), MainActivity.class); showIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); showIntent.putExtra("command", "show"); showIntent.putExtra("name", name + "from service."); startActivity(showIntent);
onStartCommand 메소드에 위와같이 인텐트를 이용한 데이터 전달 코드를 넣어주면 MainActivity에서 이 데이터를 받아볼 수 있습니다.
화면이 없는 서비스에서 화면이 있는 액티비티를 띄울 때는 태스크(Task)를 새로 만들어서 연결해야 합니다.
이 때문에 FLAG_ACTIVITY_NEW_TASK 플래그를 추가해주게 되는데 일반적인 경우 세 개의 플래그를 같이 사용합니다.
액티비티가 다시 실행될 때
MainActivity가 startActivity로 다시 실행될 땐 onCreate()가 호출되지 않고 onNewIntent()가 호출됩니다.
그래서 서비스에서 받은 인텐트를 처리할 코드를 onCreate 메소드가 아닌 onNewIntent 메소드에 넣어주어야 합니다.
@Override protected void onNewIntent(Intent intent) { //onNewIntent()로 액티비티 불릴 때 받은 intent 처리 processCommand(intent); Log.d("MyService", "onNewIntent 불림"); super.onNewIntent(intent); } private void processCommand(Intent intent){ if(intent!=null){ String command = intent.getStringExtra("command"); String name = intent.getStringExtra("name"); Toast.makeText(this, "서비스로부터 전달받은 데이터 : " + command +", "+name, Toast.LENGTH_LONG).show(); } }
*********************************************