接上文(Android Service的綁定 基礎概念篇),綁定的service主要有三種不同的實現方法,在此介紹第一種方法。
Extending the Binder class
如果你的service僅僅是被本應用所使用,不需要跨進程工作,那么你可以實現你自己的 Binder類,為客戶端提供service中public方法的直接訪問權限。
注意:這種方法只適用於客戶端和service在同一個應用的同一個進程中。
基本步驟
1.在你的service中,建立一個 Binder的實例,滿足下列三個條件之一即可:
包含客戶端可以調用的public方法。
返回當前的service實例,其中含有public方法,客戶端可以調用。
返回service中一個其他類的實例,其中含有客戶端可以調用的public方法。
2.在onBind()回調函數中返回這個Binder對象
3.在客戶端中,通過onServiceConnected()回調函數接收這個Binder對象,之后就可以通過這個對象提供的方法來調用綁定的service中的方法。
程序例子
public class LocalService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); // Random number generator private final Random mGenerator = new Random(); /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { LocalService getService() { // Return this instance of LocalService so clients can call public // methods return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } /** method for clients */ public int getRandomNumber() { return mGenerator.nextInt(100); } }
LocalBinder提供了getService()方法,這樣客戶端就可以獲取LocalService當前的實例,進一步,客戶端就可以調用public方法。
比如,客戶端可以調用getRandomNumber()方法。
下面是一個activity,和LocalService進行了綁定,並且當按鈕按下時會調用getRandomNumber()方法。
public class BindingActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @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) { 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 onButtonClick(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. int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get // LocalService instance LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; }
客戶端是通過把ServiceConnection傳遞給 bindService()
方法來進行綁定的。
比如:
Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
bindService()
的第一個參數是一個intent,顯示指定要綁定的service的名字,(這個intent也可以是隱式的);
第二個參數是ServiceConnection對象;
第三個參數是一個標志變量,作為綁定選項,它通常是BIND_AUTO_CREATE,為了在service不存在的情況下創建一個service。
其他可能的選項是 BIND_DEBUG_UNBIND 和BIND_NOT_FOREGROUND
,沒有的話可以設置為0。
參考資料
API Guides:Bound Services
http://developer.android.com/guide/components/bound-services.html