서비스
서비스란 백그라운드에서 실행되는 앱의 구성 요소를 말한다.
서비스도 앱의 구성 요소이므로 시스템에서 관리한다. 그래서 액티비티를 만들 때
매니페스트 파일에 등록했던 것처럼 새로 만든 서비스도 매니페스트 파일에 꼭 등록 해야한다.
실행 원리와 역할
서비스를 실행하려면 메인 액티비티에서 startService 메서드를 호출하면 된다.
서비스의 주요 역할 중 하나는 단말이 항상 실행되어 있는 상태로 다른 단말과 데이터를 주고 받거나
필요한 기능을 백그라운드에서 실행하는 것이다.
서비스를 시작시키기 위해 startSevice 메서드를 호출할 때는 인텐트 객체를 피라미터로 전달한다.
이 인텐트 객체는 어떤 서비스를 실행할 것인지에 대한 정보를 담고 있으며 시스템은 서비스를 시작시킨 후
인텐트 객체를 서비스에 전달한다.
서비스가 실행 중이면 실행 이후에 startService 메서드를 여러 번 호출해도 서비스는
이미 메모리에 만들어진 상태로 유지된다. 따라서 startService 메서드는 서비스를 시작하는 목적 이외에는
인텐트를 전달하는 목적으로 자주 사용된다.
액티비티에서 서비스로 데이터를 전달하려면 인텐트 객체를 만들고 부가 데이터를 넣은후
startService 메서드를 호출하면서 전달하면 된다. 이 경우 이미 서비스가 메모리에 만들어져 있는 상태 이므로,
onCreate 메서드가 아니라 onStartCommand 메서드를 실행한다.
서비스 만들어보기
app 폴더에 new -> Srvice를 클릭한다.
Class Name에는 MyService라고 입력하자.
이렇게 하면 MyService.java 파일이 만들어지고 Manifest 파일안에 service 태그도 추가된다.
자동으로 만들어진 MyService.java 파일안에는 생성자와 onBind 메서드만 있다.
우리는 서비스의 생명주기를 관해주기 위해,
onCreate, onDestroy, onStartCommand 메서드를 만들어주자.
그 후 MainActity.java 파일을 아래와 같이 수정하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class MainActivity extends AppCompatActivity {
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editTextText);
Button button = findViewById(R.id.button);
button.setOnClickListener((v)->{
String name = editText.getText().toString();
/* 인텐트 객체 만들고 부가 데이터 넣기 */
Intent intent = new Intent(getApplicationContext(), MyService.class);
intent.putExtra("command","show");
intent.putExtra("name",name);
startService(intent); // 서비스 시작하기
});
Intent passedIntent = getIntent();
processIntent(passedIntent);
}
@Override
protected void onNewIntent(Intent intent){
processIntent(intent);
super.onNewIntent(intent);
}
private void processIntent(Intent intent){
if(intent!=null){
String command = intent.getStringExtra("command");
String name = intent.getStringExtra("name");
Toast.makeText(this,"command" + ", name : " + name,
Toast.LENGTH_LONG).show();
}
}
}
서비스가 서버 역할을 하면서 액티비티와 연결될 수 있도록 만드는 것을 바인딩(Binding)
이라고하고, 이를 위해서는 onBind 메서드를 재정의해야한다.
하지만 여기서는 바인딩 기능을 사용하지 않으므로 수정하지 않고 그대로 놔둔다.
인제 MyService.java 파일을 수정해 보자.
MyService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() 호출됨.");
}
public int onStartCommand(Intent intent, int flags, int startId){
Log.d(TAG, "onStartCommand() 호출됨.");
if(intent == null)
return Service.START_STICKY;
else
processCommand(intent);
return super.onStartCommand(intent, flags, startId);
}
private void processCommand(Intent intent){
String command = intent.getStringExtra("command");
String name = intent.getStringExtra("name");
Log.d(TAG,"command : " + command + ", name : " + name);
for(int i=0; i<5; i++){
try{
Thread.sleep(1000);
}catch (Exception e){};
Log.d(TAG, "Waiting " + i + "seconds.");
}
Intent showIntent = new Intent(getApplicationContext(), MainActivity.class);
showIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|
Intent.FLAG_ACTIVITY_SINGLE_TOP|
Intent.FLAG_ACTIVITY_CLEAR_TOP);
showIntent.putExtra("command","show");
showIntent.putExtra("name",name+" from service.");
startActivity(showIntent);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
결과