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
'Android' 카테고리의 다른 글
[Android]현재 날짜(년-월-일-시-분-초) 구하기(SimpleDateFormat) (0) | 2017.09.07 |
---|---|
[Android]안드로이드 앱 마켓 버전 체크 (0) | 2017.08.27 |
[Android]폴더 삭제하기(하위 폴더 및 파일까지) (0) | 2017.08.13 |
[Android]Service 생명주기 (0) | 2017.08.11 |
[Android]ProgressDialog 사용하기 (0) | 2017.08.07 |