(210518 수정)
앱이 실행되고 있다고 할지라고 반드시 화면이 보이는 것은 아니다.
예를 들어, 음악을 재생한 경우 앱이 실행은 되어있지만 소리만 나오고 화면은 보이지 않는다.
이것은 화면없이 백그라운드(배경)에서 실행되는 '서비스(Service)' 가 있기 때문이다.
서비스도 앱의 구성 요소(컴포넌트)이므로 시스템에서 관리한다.
그러므로 매니페스트에 반드시 등록을 해줘서 시스템이 알 수 있게 해줘야한다.
그리고 서비스는 단말이 항상 실행되어 있는 상태로써,
다른 단말과 데이터를 주고받거나 필요한 기능을 백그라운드에서 실행하는데
그 실행된 상태를 유지하기 위해 서비스가 비정상적으로 종료가 되더라도
시스템이 자동으로 재실행하게 된다.
서비스를 실행하려면 액티비티의 startService() 메소드에 인텐트 객체를 파라미터로 담아서 호출해야한다.
이 인텐드 객체에는 어떠한 서비스를 실행할 것인지, 어떤 부가 데이터를 넣은 것인지에 대한 정보를
담고 있으며, 시스템은 서비스를 실행시킨 후 인텐트 객체를 서비스에 전달하게된다.
그러나 startService() 메소드를 한 번이상 여러번 호출해서
서비스가 이미 메모리에 만들어진 상태로 유지되는 경우에는
서비스가 시작하는 목적 이외에 인텐트를 전달하는 목적으로도 사용된다.
이러한 경우에는 시스템이 onCreate() 가 아니라 onStartCommand() 메소드를 실행하게된다.
즉, onStartCommand() 메소드는 서비스로 전달된 인텐트 객체를 처리하는 메소드라는 것이다.
이번 시간에는 버튼을 누르면 입력창에 입력한 문자열이 서비스의 이름(데이터)이 되어
서비스로 인텐트를 전달하게 되고. 그 서비스는 인텐트로 받은 데이터를 로그로 출력하고,
그 데이터를 다시 액티비티로 인텐트를 넘겨서 액티비티에서는 토스트 메시지로 데이터를 출력하는 기능을
만들어볼 것이다.
다음과 같이 간단하게 화면을 구성하였다.
자바 클래스 파일은
데이터를 인텐트에 담아서 주고 받아야 하기 때문에
액티비티 클래스 하나와 서비스 클래스 하나가 필요하다.
먼저 MainActivity.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
|
public class MainActivity extends AppCompatActivity {
EditText edt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edt = (EditText)findViewById(R.id.edt);
Button btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = edt.getText().toString(); // EditText에 입력한 값을 가져와서 name에 할당
Intent intent = new Intent(getApplicationContext(), SendService.class); // 인텐트를 생성하고 부가 데이터 넣기
intent.putExtra("name", name); // EditText에 입력한 값 name을 인텐트에 넣음
startService(intent); // 인텐트를 담아서 서비스를 시작시킴(SendService 클래스로 전달)
}
});
// 메인 액티비티가 메모리에 만들어져 있지 않은 상태에서 새로 만들어질 때 전달된 인텐트 처리
Intent passedIntent = getIntent(); // 인텐트 객체를 가져옴
processIntent(passedIntent);
}
public void onNewIntent(Intent intent) { // 액티비티가 이미 만들어져 있을 때 전달된 인텐트 처리
processIntent(intent);
super.onNewIntent(intent);
}
public void processIntent(Intent intent) {
if(intent != null) {
String name = intent.getStringExtra("name"); // 인텐트에서 name 키를 가져와서 name에 할당
Toast.makeText(this, name + "을/를 받았습니다. ", Toast.LENGTH_SHORT).show();
}
}
}
|
cs |
그리고 SendService.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
53
54
55
56
57
58
59
|
public class SendService extends Service { // 서비스를 상속해야함
private static final String TAG = "SendService"; // 로그 메시지 구분 태그
public SendService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() 호출됨. ");
}
@Override // 인텐트를 여기서 처리함
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand() 호출됨. ");
if(intent == null) {
return Service.START_STICKY; // 서비스가 강제종료되면 시스템이 서비스의 인텐트 값을 null로 초기화해서 재시작시킴
} else {
processCommand(intent);
}
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void processCommand(Intent intent) {
// 인텐트에서 부가 데이터 가져오기
String name = intent.getStringExtra("name"); // 인텐트에서 name 이라는 키의 값을 가져와서 name에 할당
Log.d(TAG, "서비스 이름 : " + name ); // 버튼을 누르면 입력정보가 로그로 출력됨
for(int i = 5; i >= 0; i--) {
try {
Thread.sleep(1000);
} catch (Exception e) {
};
Log.d(TAG, i + "초만 기다리세요. ");
}
Intent showIntent = new Intent(getApplicationContext(), MainActivity.class); // 액티비티를 띄우기 위한 인텐트 객체 생성
// 생성한 인텐트에 플래그 추가
showIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | // 새로운 태스크(화면이 없는 서비스에서 화면이 있는 액티비티를 띄우기위함
Intent.FLAG_ACTIVITY_CLEAR_TOP | // 액티비티 위의 다른 액티비티 제거
Intent.FLAG_ACTIVITY_SINGLE_TOP); // 객체가 이미 메모리에 만들어져 있을 때 재사용
showIntent.putExtra("name", "서비스에서 보낸 " + name); // 인텐트에 name을 넣음
startActivity(showIntent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
|
cs |
그리고 매니페스트에 서비스를 등록해줘야 실행이 가능하다.
<service android:name=".SendService" />
이렇게 모두 작성하고
입력창에 '서비스테스트'라고 입력하게되면
액티비티에서 서비스로 인텐트가 전달되기 때문에
다음과 같이 로그가 출력이 된다.
그리고 "0초만 기다리세요" 라고 뜨는 순간
서비스에서 액티비티로 인텐트가 전달되기 때문에
다음과 같은 토스트 메시지가 출력이 된다.
이렇게 액티비티와 서비스가 인텐트에 데이터를 담아서
서로 주고 받는 기능을 알아보았다.
서비스는 앱에서 아주 많이 쓰이는 기능으로써
꼭 확실하게 알아두도록 하자.
피드백은 언제나 환영입니다.
'프로그래밍(programming) > 안드로이드(android)' 카테고리의 다른 글
[210524] 안드로이드 방송 수신자 / 브로드 캐스트 리시버(Brodcast Receiver) - SMS 문자 받아서 출력 (0) | 2021.05.24 |
---|---|
[210521] 안드로이드 매니페스트(Manifest) (0) | 2021.05.21 |
[210512] 안드로이드 커스텀뷰(CustomView)를 이용한 그래픽 그리기 / Canvas 객체와 Paint 객체 (0) | 2021.05.12 |
[210511] 안드로이드 시크바(SeekBar) (0) | 2021.05.11 |
[210509] 안드로이드 데이터베이스와 테이블의 생성과 데이터의 삽입과 조회 (0) | 2021.05.09 |