본문 바로가기

Programming/Android

Service 사용

1. Service


Service는 안드로이드 4대 컴포넌트 [Activity, Broadcast receiver, Content provider, Service] 중 하나이다.

코드가 동작하는 것은 같지만 사용자가 무언가 조작을 하기 위해서 필요한 것이 아니라, 앱을 종료하더라도 지속해서 돌아가야 하는 [ex. 음악앱, 메신저앱] 등을 만들 때 주로 쓰인다. 안드로이드에서는 Service가 실행되고 있는 상태라면 메모리 부족같은 특수한 경우가 아니라면 service가 돌아가고 있는 process를 없애지 않고 지속적으로 관리한다. 그렇기 때문에 지속적으로 background에서 돌아가야 하는 앱에 적합하다.


2. Type


Service에는 두가지 타입이 있다. Start service와 Bind service가 그것이다.

Start service는 startService()를 사용하고 Bind service는 bindService()를 사용하게 되는데 둘의 차이는 이렇다.

Start service는 한번 시작해서 백그라운드에서 무한정 자신이 맡은 역할을 끝낼때까지 수행하는 형태.

Bind service는 Server나 다른 Activity에 연결되어 데이터를 주고 받으며 연산을 행하는 형태.


두 가지 타입을 한번에 지니는 것도 가능하며, 두 가지 타입을 한번에 구현하고 싶을 때에는 startService와 Bindservice의 메소드를 동시에 구현해주면 된다.


startService()

- 받는 쪽과 묶어서 돌아가는 구조

- 호출 순서 : onCreate() -> onStart() ->  ... -> onDestory()

- service가 실행중인 상태라면 startService() 가 호출되도 상태 유지, 서비스 종료상태에서 stopService()하면 아무 일도 발생하지 않는다.

- bindService로 실행된 서비스를 startService로 호출하게 되면 이전(bindService) 관리는 무시되고 새로운 상태로 변경된다.

- service가 resource를 너무 많이 사용하게 되면 system에 의해 종료될 수 있다.


bindService()

- 서비스 받는 쪽과 상관없이 돌아가는 구조

- 호출 순서 : onCreate() -> onBind() -> ... -> onRebind -> ...  -> onUnbind() -> onDestory()

- 호출한 객체가 존재하면 system은 service가 필요하다고 판단하여 실행, 재실행 등으로 유지한다.

   (호출 객체 소멸시 system에서 필요없다고 판단하면 언제든지 중지)


3. 예시


- startService()

  startService() 를 호출하여서 서비스를 시작하면, stopSelf() 를 호출하거나 다른 컴포넌트가 stopService() 를 호출할 때까지 실행을 계속한다.


 1 - 프로젝트 생성 후 메인 액티비티 생성.

 2 - New -> Service -> Service 클래스 생성. 


import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

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");
}
}


 3 - code -> Override Method 에서 재정의 할 메소드를 추가한다. onCreate(), onStartCommand(), onDestroy() 메소드 추가.



public class MyService extends Service {
public MyService() {
}

@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();
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}


 4 - Service를 이용할 코드 삽입.[본 예시에서는 mp3 play를 합니다.]


 


public class MyService extends Service {

MediaPlayer mp3;
public MyService() {
}

@Override
public void onCreate() {
super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mp3 = MediaPlayer.create(this, R.raw.music);
mp3.setLooping(true);
mp3.start();
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}


5. 인텐트를 사용하여 Service 실행/ 중단.



public class MainActivity extends AppCompatActivity {


Button startBtn;
Button endBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

startBtn = (Button) findViewById(R.id.startBtn);
endBtn = (Button) findViewById(R.id.endBtn);

startBtn.setOnClickListener(new View.OnClickListener(){

@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
});

endBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MyService.class);
stopService(intent);
}
});
}
}