Android Service Binding, Thread handling
안드로이드의 Service 에서 실행되는 Thread를 Activity에서 제어하는 예
액티비티에서 서비스를 바인딩하는 방법을 이용하면 액티비티가 서비스의 참조를 가진 상태에서 서비스를 직접 제어할 수 있게 된다
servicebind.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onBtnStart" android:text="Start thread within Service" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onBtnStop" android:text="Stop thread within Service" /> </LinearLayout>
LocalService.java
package com.example.androidapp; import java.util.Date; import java.util.Random; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class LocalService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); public boolean go = false; public class LocalBinder extends Binder { LocalService getService() { // Activity에서 호출하면 서비스 클래스의 인스턴스를 리턴함 // Return this instance of LocalService so clients can call public methods return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } public void startThread() { go = true; new Thread() { @Override public void run() { while(go) { Date date = new Date(); Log.i("오늘날짜", date.toString()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } public void stopThread() { go = false; } }
ServiceBindingActivity.java
package com.example.androidapp; import com.example.androidapp.LocalService.LocalBinder; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.widget.Toast; public class ServiceBindingActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.servicebind); } @Override protected void onStart() { super.onStart(); // Bind to LocalService Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { mService.stopThread(); unbindService(mConnection); mBound = false; } } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute) */ public void onBtnStart(View v) { if (mBound) { // Call a method from the LocalService. // However, if this call were something that might hang, then this request should // occur in a separate thread to avoid slowing down the activity performance. mService.startThread(); } } public void onBtnStop(View v) { if(mBound) { mService.stopThread(); } } /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { // 아래의 두번째 파라미터에는 Service측의 onBind()에서 리턴한 IBinder 객체가 전달됨 public void onServiceConnected(ComponentName className,IBinder binder) { // We've bound to LocalService, cast the IBinder and get LocalService instance LocalBinder localBinder = (LocalBinder) binder; mService = localBinder.getService(); mBound = true; Log.i("service 상태", "서비스 연결됨"); } public void onServiceDisconnected(ComponentName arg0) { mBound = false; Log.i("service 상태", "서비스 연결해제됨"); } }; }