Binding Service Usage
When binding services, the most important thing is to define the interface returned by the onbind () callback method. There are three methods:
1. inherit the binder class
2. Use messenger
3. Use aidl
The method 1 and 2 is analyzed here.
1. inherit the binder class
If your service is a private service of your application and runs in the same process as the client, you should create your interface by inheriting the binder class, in addition, Buddha returns an instance of this interface from the onbind () method. The client receives this binder object and can use this object to directly access the public methods implemented in the binder class or in the service.
Example in the official SDK documentation:
Serviceshow. Java
Package COM. luoye. servicelearn; import Java. util. random; import android. app. service; import android. content. intent; import android. OS. binder; import android. OS. ibinder; public class serviceshow extends Service {private final ibinder binder = new localbinder (); // create a Service's internal ibinder object public class localbinder extends binder {serviceshow getservice () // implement the binder's own method. Here, the reference of the service object {return serviceshow. this ;}} public int getrandomnumber () {return (new random ()). nextint (100) ;}@ overridepublic ibinder onbind (intent) {// todo auto-generated method stub // returns an ibinder object, that is, the internal ibinder object of the service, passed return binder as the ibinder of the onserviceconnected method in serviceconnection ;}}
Mainactivity. Java
Package COM. luoye. servicelearn; import COM. luoye. servicelearn. serviceshow. 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. view; import android. widget. toast; public class mainactivity extends activity {serviceshow LocalService; Boolean bound = false; @ overrideprotected void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. activity_main) ;}@ overridepublic Boolean oncreateoptionsmenu (menu) {// inflate the menu; this adds items to the action bar if it is present. getmenuinflater (). inflate (R. menu. main, menu); Return true;} public void buttononclicklistener (view v) {Switch (v. GETID () {case R. id. start_service1: intent intent_start = new intent (this, serviceshow. class); // bind the second parameter of the Service to the serviceconnection object. Because bindservice is asynchronous, The // bindservice () method returns immediately without returning the ibinder object, therefore, you need to process the serviceconnection method // bind_auto_create indicates that if service does not exist, that is, oncreate () bindservice (intent_start, connection, context. bind_auto_create); break; case R. id. stop_service1: If (bound) {unbindservice (connection); bound = false;} // unbind servicebreak; case R. id. show_random: If (bound = true) {toast. maketext (this, "number is:" + LocalService. getrandomnumber (), toast. length_short ). show ();} break;} private serviceconnection connection = new serviceconnection () {@ overridepublic void onserviceconnected (componentname, ibinder Service) {// todo auto-generated method stublocalbinder binder = (localbinder) service; // obtain the Service's ibinder object LocalService = binder. getservice (); // get the reference of the service. Then you can use the service method bound = true ;}@ overridepublic void onservicedisconnected (componentname name) {// todo auto-generated method stubbound = false ;}};}
2. Use messenger
If the service needs to communicate with a remote process, you can use the messenger object to provide interfaces for the service.
The following is a brief introduction to the use of messenger objects:
1. A server-side processor (handler Interface) receives a callback for each call from the client;
2. This processor is used to create a Messager (this messenger object will reference this processor );
3. Create a messenger object to create an ibinder object that the server returns to the client from the onbind () method;
4. The client uses this ibinder object to instantiate this messenger object (the messenger references the server's processor), and the client uses this messenger to send a message object to the server;
5. The server receives each message object in sequence in the handlemessage () method of its processor (handler ).
In this method, the client does not provide a method call from the server. On the contrary, the client sends a message to the server, and the Server accepts the message objects in its processor.
Code:
Serviceshow. Java
Package COM. luoye. servicelearn; import android. app. service; import android. content. intent; import android. OS. handler; import android. OS. ibinder; import android. OS. message; import android. OS. messenger; import android. widget. toast; public class serviceshow extends Service {static final int msg_code = 0x10; // Message Type Definition class incominghandler extends handler // message processor, {public void handlemessage (Message MSG) {Switch (MSG. what) {Case msg_code: Toast. maketext (serviceshow. this, "Hello World", toast. length_short ). show (); break; default: Super. handlemessage (MSG) ;}}// create a messenger that uses the handler object as the MSG processor final messenger = new messenger (New incominghandler ()); @ overridepublic ibinder onbind (intent) {// todo auto-generated method stubtoast. maketext (serviceshow. this, "binding", toast. length_short ). show (); Return messenger. getbinder (); // return the binder of the corresponding messenger and return it to the client }}
Mainactivity. Java
Package COM. luoye. servicelearn; 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. OS. message; import android. OS. messenger; import android. view. menu; import android. view. view; public class mainactivity extends activity {messenger; Boolean bound = false; @ overrideprotected void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. activity_main) ;}@ overridepublic Boolean oncreateoptionsmenu (menu) {// inflate the menu; this adds items to the action bar if it is present. getmenuinflater (). inflate (R. menu. main, menu); Return true;} public void buttononclicklistener (view v) {Switch (v. GETID () {case R. id. start_service1: intent intent_start = new intent (this, serviceshow. class); // bind the second parameter of the Service to the serviceconnection object. Because bindservice is asynchronous, The // bindservice () method returns immediately without returning the ibinder object, therefore, you need to process the serviceconnection method // bind_auto_create indicates that if service does not exist, that is, oncreate () bindservice (intent_start, connection, context. bind_auto_create); If (bound) {// generates the message object message MSG = message. obtain (null, serviceshow. msg_code, 0, 0); try {// use the client-side messenger to send the message. The message will be submitted to the service-side by the messenger corresponding to the binder. // messenger, and the message processor handler used by this terminal processes the messenger. send (MSG);} catch (exception e) {e. printstacktrace () ;}} break; case R. id. stop_service1: If (bound) {unbindservice (connection); // unbind servicebound = false;} break;} private serviceconnection connection = new serviceconnection () {@ overridepublic void onserviceconnected (componentname, ibinder Service) {// todo auto-generated method stubmessenger = new messenger (service ); // use the ibinder corresponding to the messenger returned by the Service to create the client messenger object bound = true;} @ overridepublic void onservicedisconnected (componentname name) {// todo auto-generated method stubmessenger = NULL; bound = false ;}};}