◎4대 주요 구성요소 [면접때 물어보기도 합니다.]
1) Activity - 화면 담당
2) Service - 백그라운드 작업
3) Broadcast Receiver - 디바이스 상태 정보 사용
4) Content Provider - 다른 앱에 Data 제공
버튼을 눌러서 음악파일을 재생 시키고, 앱을 종료되도 Background에서도 동작되게 하자.
[예제에서는 kalimba 음악파일을 사용했다. 음악파일은 각자 알아서 준비!!]
음악을 먼저 추가하고
이제 클래스를 만들자.
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
|
package com.lcw.ex64servicebindtest;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class MusicService extends Service {
MediaPlayer mp;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(mp==null){
mp.setLooping(false);
mp.setVolume(1.0f,1.0f);
}
return START_STICKY;
}
@Override
public void onDestroy() {
if(mp!=null){
mp.release();
mp=null;
}
super.onDestroy();
}
}
|
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
|
package com.lcw.ex64servicebindtest;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void clickStart(View view) {
Intent intent= new Intent(this,MusicService.class);
startService(intent);
}
public void clickStop(View view) {
Intent intent= new Intent(this, MusicService.class);
stopService(intent);
}
}
|
이렇게하면 START 버튼을 누르면 음악이 나오고, STOP 버튼을 누르면 음악이 종료된다.
그리고 START 버튼을 누르고 앱을 종료시켜도 음악이 나온다.
그리고 앱을 다시 들어가서 STOP을 누르면 정상적으로 음악이 종료된다.
여기서 음악을 일시 중지 버튼을 추가해보자. (어려움!! )
[생각해보면 Service에 pause() 는 있지만 이것을 제어하기 위해 MainActivity 에서 참조변수를 이용해야한다.]
우선 pause 버튼을 만들고, MusicService 클래스 내용을 수정해야한다. (거의 그냥 새로 만드는 수준으로 내용이 바뀐다.)
보통 startService()로 시작하여 [만들지 않았다면==null이면] onCreate를 자동 실행한다.
그 다음 onStartCommand()로 서비스 실행하고, stopService()를 해야만 background 작업이 종료된다.
여기서 bindService는 총 한개의 MainActivity만 연결되 있다면 그 MainActivity가 종료되면 자동으로 종료된다. -차이점
bindService는 그럼 왜 사용하느냐, 멀티 채팅의 경우 사용한다.
이제 다시 쓰는 예제는 백그라운드 작업을 위해 Service를 사용하고 binService로 Service 참조 값을 MainActivity에 넘겨주기 위해 사용한다.
대략적 순서는 MainActivity-onCreate → MainActivity-onResume[여기에서 Service객체 생성 및 주소를 받아와서 연결작업 (객체가 있다면 자동으로 다시 만들지 않는다.)] → MusicService-onBind()[여기서 주소를 넘겨줌] → 사용자임의START, PAUSE, STOP 버튼을누른다.
activity_main.xml 코드
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
|
<?xml version="1.0" encoding="utf-8"?>
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="START"
android:onClick="clickStart"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pause"
android:onClick="clickPause"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="STOP"
android:onClick="clickStop"/>
</LinearLayout>
|
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
package com.lcw.ex64servicebindtest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
public class MainActivity extends AppCompatActivity {
MusicService musicService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//액티비티가 화면에 보여질때 자동으로 실행되는 라이프사이클 콜백 메소드
@Override
protected void onResume() {
super.onResume();
//서비스 객체와 연결작업 수행
if(musicService==null){
Intent intent=new Intent(this,MusicService.class);
startService(intent);// Service객체가 없다면 create를 하고 on StartCommand() 메소드를 호출하며, 있다면 onStartCommand()만 실행함.
//서비스 객체의 참조값을 얻어오기 위해
//서비스 객체와 연결(bind)하는 메소드를 호출
bindService(intent, conn, 0); // bind할 때 flags :0은 onCreate()를 하지 않겠다. (서비스 객체를 자동 만들지 않음.)
}
}
//MusicService객체와 연결 상태를 관리하는 객체 생성[터널 객체]
ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) { // MusicService 클래스에 onBind 리턴 값(MusicService 참조 값[주소])이 iBinder로 넘어옴
//연결되었을 때 실행되는 콜백메소드
//연결된 터널을 통해 서비스객체의 참조값 얻어오기
//서비스로 부터 넘어온 외교관 객체(iBinder) 에게 서비스 객체의 참조값 얻어오기
MusicService.ServiceBinder binder= (MusicService.ServiceBinder) iBinder;
musicService=binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
public void clickStart(View view) {
if(musicService!=null) musicService.playMusic();
}
public void clickPause(View view) {
if(musicService!=null) musicService.pauseMusic();
}
public void clickStop(View view) {
if(musicService!=null){
musicService.stopMysic();
unbindService(conn);
musicService=null;
}
Intent intent=new Intent(this,MusicService.class);
stopService(intent);
finish();
}
}
|
MusicService.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
60
61
62
63
64
65
66
67
|
package com.lcw.ex64servicebindtest;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class MusicService extends Service {
MediaPlayer mp;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//START_STICKY : kill 되었다가 다시 메모리 문제가 해결되면 자동 실행되도록 하는 리턴값.
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
//bindService()를 실행하면 발동하는 메소드
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new ServiceBinder(); //외교관 리턴- MainActivity 에서 사용 가능
}
//MainActivity 와 bind 되었을 때
//넘어갈 객체 클래스(외교관 역할)
class ServiceBinder extends Binder {
//이 MusicService 객체의 참조값을
//리턴하는 기능 메소드
MusicService getService(){
return MusicService.this;
}
}
public void playMusic(){
if(mp==null){
mp.setLooping(true);
mp.setVolume(1.0f, 1.0f);
}
}
public void pauseMusic(){
}
public void stopMysic(){
if(mp!=null){
mp.release();
mp=null;
}
}
}
|
이렇게 완성하면 뮤직 앱처럼 음악을 틀고, 앱을 종료시켜도 음악이 계속 흘러 나온다.
그리고 앱을 들어가서 일시 중지 시키면 노래가 멈추고, 다시 플레이 가능하다.
물론 종료도 잘 작동한다.
'안드로이드 웹앱 콘테츠 개발자 양성(국비지원) > Android 기능' 카테고리의 다른 글
Android Studio(기능) Location / Map 각 사이트 이용 방법 (0) | 2019.10.11 |
---|---|
Android Studio(기능) LBS 3 (지도 앱에 해당 위치 표시하기) (0) | 2019.10.10 |
Android Studio(기능) LBS 2(Location Test) (0) | 2019.10.10 |
Android Studio(기능) LBS(Location Test) (0) | 2019.10.10 |
Android Studio(기능) Service (0) | 2019.10.08 |
댓글