1. Bound Services
A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send
requests, receive responses, and even perform interprocess communication (IPC). A bound service typically lives only while it serves
another application component and does not run in the background indefinitely
2. The Basics
A bound service is an implementation of the Services class that allows other applications to bind to it and interact with it. To provide binding
for a service, you must implement the onBind() callback method. This method returns an IBinder object that defines the programming
interface that clients can use to interact with the service.
3. Creating a Bound Service
When creating a service that provides binding, you must provide an IBinder
that provides the programming interface that clients can use to
interact with the service. There are three ways you can define the interface:
<1>Extending the Binder class
<2>Using a Messenger
<3>Using AIDL
4. Extending the Binder class
If your service is private to your own application and runs in the same process as the client (which is common), you should create your
interface by extending the Binder
class and returning an instance of it from onBind()
. The client receives the Binder
and can use it to
directly access public methods available in either the Binder
implementation or even the Service
.
This is the preferred technique when your service is merely a background worker for your own application. The only reason you would not
create your interface this way is because your service is used by other applications or across separate processes.
//activity_bingding.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="mirror.android.extendingbinder.BindingActivity" > <Button android:id = "@+id/btn_create_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Create service" /> </RelativeLayout>
//LocalService.class package mirror.android.extendingbinder; import java.util.Random; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; public class LocalService extends Service { private final IBinder mBinder = new LocalBinder(); private final Random mGenerator = new Random(); /*1.In your service, create an instance of Binder that either: * <1> contains public methods that the client can call * <2> returns the current Service instance, which has public methods the client can call * <3> or, returns an instance of another class hosted by the service with public methods the client can call */ public class LocalBinder extends Binder{ LocalService getService(){ return LocalService.this; } } /*2.Return this instance of Binder from the onBind() callback method. */ @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return mBinder; } /*The LocalBinder provides the getService() method for clients to retrieve the current instance of LocalService. *This allows clients to call public methods in the service. *For example, clients can call getRandomNumber() from the service.*/ public int getRandomNumber(){ return mGenerator.nextInt(); } }
//BindingActivity.class package mirror.android.extendingbinder; import mirror.android.extendingbinder.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.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class BindingActivity extends Activity { private Button button; LocalService mService; Boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_binding); button = (Button)findViewById(R.id.btn_create_service); ButtonListener buttonListener = new ButtonListener(); button.setOnClickListener(buttonListener); } @Override protected void onStart() { super.onStart(); //1.bind to LocalService Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onPause() { super.onPause(); } @Override protected void onStop() { super.onStop(); //2.unbind from service if(mBound){ unbindService(mConnection); mBound = false; } } class ButtonListener implements OnClickListener{ //3.Call a method from the LocalService. //create a separate thread if needed; @Override public void onClick(View v) { if(mBound){ int num = mService.getRandomNumber(); Toast.makeText(getApplicationContext(), "number: " + num, Toast.LENGTH_SHORT).show(); } } } private ServiceConnection mConnection = new ServiceConnection() { //3.In the client, receive the Binder from the onServiceConnected() callback method // and make calls to the bound service using the methods provided. @Override public void onServiceDisconnected(ComponentName name) { mBound = false; } @Override public void onServiceConnected(ComponentName name, IBinder service) { LocalBinder binder = (LocalBinder)service; mService = binder.getService(); mBound = true; } }; }
//manifest.xml <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".BindingActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".LocalService"></service> </application>
5. Using a Messenger
If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service.
This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.