본문 바로가기

Android

[Android]BindService 간단 구현 및 사용법(서비스와 액티비티 통신)

반응형

BindService는 startService()를 통해 시작되는 UnBound Service와는 다르게


액티비티 및 프래그먼트와 데이터를 주고 받을 수 있으며


프로세스간의 통신에도 사용됩니다.


쉽게 말하면 서비스를 실행시켜두고 필요할 때 마다 서비스의 메소드에 접근하여 통신할 수 있는 구조입니다.


아래의 예제 코드는 http://bitsoul.tistory.com/149 해당 글의 예제코드를 참고하여 살을 조금 더 붙였습니다.


원작자님께 감사드립니다.



두 개의 액티비티가 하나의 서비스의 데이터를 전달받는 것이 해당 예제코드의 목적입니다.



[서비스 : 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
public class MyService extends Service {
    private final IBinder mBinder = new LocalBinder();
    private int number;
 
    class LocalBinder extends Binder {
        MyService getService() {
            return MyService.this;
        }
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(getApplicationContext(), "Service Created", Toast.LENGTH_SHORT).show();
        number = 0;
    }
 
    int getNumber(){
        return number++;
    }
}
cs





[시작 액티비티 : StartActivity.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class StartActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
 
        Button startButton = (Button)findViewById(R.id.startButton);
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(StartActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }
}
cs






[첫 번째 액티비티 : 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
78
79
80
81
82
83
84
85
86
87
88
public class MainActivity extends AppCompatActivity {
 
    MyService myService;
    boolean isService = false// 서비스 중인 확인용
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        Button b1 = (Button) findViewById(R.id.button1);
        Button b2 = (Button) findViewById(R.id.button2);
        Button b3 = (Button) findViewById(R.id.button3);
        Button b4 = (Button) findViewById(R.id.button4);
 
        b1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { // 서비스 시작
                Intent intent = new Intent(
                        MainActivity.this// 현재 화면
                        MyService.class); // 다음넘어갈 컴퍼넌트
 
                bindService(intent, // intent 객체
                        conn, // 서비스와 연결에 대한 정의
                        Context.BIND_AUTO_CREATE);
            }
        });
        b2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { // 서비스 종료
                if(isService){
                    unbindService(conn); // 서비스 종료
                    isService = false;
                }
                else{
                    Toast.makeText(MainActivity.this"연결된 서비스 없음", Toast.LENGTH_SHORT).show();
                }
            }
        });
        b3.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { // 서비스 데이터 확인
                if (!isService) {
                    Toast.makeText(getApplicationContext(),
                            "서비스중이 아닙니다, 데이터받을수 없음",
                            Toast.LENGTH_LONG).show();
                    return;
                }
                int num = myService.getNumber();//서비스쪽 메소드로 값 전달 받아 호출
                Toast.makeText(getApplicationContext(),
                        "받아온 데이터 : " + num,
                        Toast.LENGTH_LONG).show();
            }
        });
        b4.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { // 액티비티 이동
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intent);
            }
        });
    }
 
    ServiceConnection conn = new ServiceConnection() {
        public void onServiceConnected(ComponentName name,
                                       IBinder service) {
            // 서비스와 연결되었을 때 호출되는 메서드
            // 서비스 객체를 전역변수로 저장
            MyService.LocalBinder mb = (MyService.LocalBinder) service;
            myService = mb.getService(); // 서비스가 제공하는 메소드 호출하여
            // 서비스쪽 객체를 전달받을수 있슴
            isService = true;
        }
 
        public void onServiceDisconnected(ComponentName name) {
            // 서비스와 연결이 끊겼을 때 호출되는 메서드
            isService = false;
            Toast.makeText(getApplicationContext(),
                    "서비스 연결 해제",
                    Toast.LENGTH_LONG).show();
        }
    };
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(isService){
            unbindService(conn); // 서비스 종료
            isService = false;
        }
    }
}
cs






[두 번째 액티비티 : Main2Activity.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
78
79
80
81
public class Main2Activity extends AppCompatActivity {
 
    MyService myService;
    boolean isService = false// 서비스 중인 확인용
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
 
        Button b1 = (Button) findViewById(R.id.button1);
        Button b2 = (Button) findViewById(R.id.button2);
        Button b3 = (Button) findViewById(R.id.button3);
 
        b1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { // 서비스 시작
                Intent intent = new Intent(
                        Main2Activity.this// 현재 화면
                        MyService.class); // 다음넘어갈 컴퍼넌트
 
                bindService(intent, // intent 객체
                        conn, // 서비스와 연결에 대한 정의
                        Context.BIND_AUTO_CREATE);
            }
        });
        b2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { // 서비스 종료
                if(isService){
                    unbindService(conn); // 서비스 종료
                    isService = false;
                }
                else{
                    Toast.makeText(Main2Activity.this"연결된 서비스 없음", Toast.LENGTH_SHORT).show();
                }
            }
        });
        b3.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) { // 서비스 데이터 확인
                if (!isService) {
                    Toast.makeText(getApplicationContext(),
                            "서비스중이 아닙니다, 데이터받을수 없음",
                            Toast.LENGTH_LONG).show();
                    return;
                }
                int num = myService.getNumber();//서비스쪽 메소드로 값 전달 받아 호출
                Toast.makeText(getApplicationContext(),
                        "받아온 데이터 : " + num,
                        Toast.LENGTH_LONG).show();
            }
        });
 
    }
 
    ServiceConnection conn = new ServiceConnection() {
        public void onServiceConnected(ComponentName name,
                                       IBinder service) {
            // 서비스와 연결되었을 때 호출되는 메서드
            // 서비스 객체를 전역변수로 저장
            MyService.LocalBinder mb = (MyService.LocalBinder) service;
            myService = mb.getService(); // 서비스가 제공하는 메소드 호출하여
            // 서비스쪽 객체를 전달받을수 있슴
            isService = true;
        }
        public void onServiceDisconnected(ComponentName name) {
            // 서비스와 연결이 끊겼을 때 호출되는 메서드
            isService = false;
            Toast.makeText(getApplicationContext(),
                    "서비스 연결 해제",
                    Toast.LENGTH_LONG).show();
        }
    };
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(isService){
            unbindService(conn); // 서비스 종료
            isService = false;
        }
    }
}
cs



액티비티들의 레이아웃은 코드를 보고 직접 버튼 몇 개만 추가하시면 됩니다.






[실행화면]


실행하자마자 보이는 화면입니다.








서비스 시작 버튼을 처음 누르면

화면에서 보이는 것 처럼

서비스가 생성되었다는 메시지를 띄웁니다.

처음 생성한 이후에는 서비스 시작 버튼을 눌러도

MyService.java 에서

onCreate를 건너뛰기 때문에 메시지가 날라오지 않습니다.









데이터 확인하기 버튼을 누를 때 마다

0에서 1씩 증가합니다.

다음 액티비티 버튼을 눌러 두 번째 액티비티로 넘어가겠습니다.









두 번째 액티비티로 넘어 온 후 데이터 확인하기 버튼을 누르자

다음과 같은 메시지가 뜹니다.

아직 두 번째 액티비티에서는 서비스를 바인딩하지 않았기 때문입니다.

서비스 시작 버튼을 누른 후 데이터 확인하기 버튼을 누르면









첫 번째 액티비티에서 1씩 증가된 숫자를 그대로 이어 받아서 1씩 증가시킵니다.

즉, 첫 번째 액티비티에서 생성한 서비스에 접근하고 있습니다.









백버튼을 눌러 다시 첫 번째 액티비티로 넘어와서 데이터 확인하기 버튼을 눌러봅니다.

역시 숫자는 그대로 유지된채로 1씩 증가가 됩니다.






이렇듯 다수의 액티비티에서 하나의 서비스에 지속적으로 접근해야할 작업이 있을 시에는

BindService를 이용하시면 되겠습니다.



다시 한번 원 출처를 남기면서 원작자분께 감사의 표현을 하겠습니다.

출처 : http://bitsoul.tistory.com/149



해당 예제 코드는 GitHub에서도 만나볼 수 있습니다.

https://github.com/NewLand-Ju/BindServiceStudy


반응형