接上文(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