Android study note 24. Service entry (2) bind and communicate with the local Service, android. service
Bind and communicate with the local ServiceThrough the first three steps in the previous blog, we have completed a Service and the application that uses the Service (the Service is an integral part of the application ). However, when a program starts or closes a Service through startService () and stopService (), there are basically no many associations between the Service and its visitors, therefore, services and visitors cannot communicate and exchange data. If we want to implement method call or data exchange between the developed Service and the visitor, we can enable or disable the Service by using the bindService () and unbindService () methods, this allows you to bind a visitor to a local Service.1. Service Startup MethodContext. bindService (Intent service, ServiceConnection conn, int flags) parameter description: service: this parameter is used to set the Service that the Activity uses Intent to start. conn: this parameter is a ServiceConnection object, this object is used to monitor the connection between the visitor and the Service. When the connection between the visitor and the Service is successful, the onServiceConnected (ComponentName, IBinder service) method of the ServiceConnection object will be called back. When the host process of the Service is terminated due to exceptions or other reasons, the onServiceDisconnected (ComponentName) method of the ServiceConnection object is called back when the Service is disconnected from the visitor. Note: When the caller actively disconnects from the Service through the unBindService () method, the onServiceDisconnected (ComponentName) method of the ServiceConnection object will not be called. Flags: Specifies whether to automatically create a Service when binding (if the Service has not been created ). Flags = 0, not automatically created; flags = BIND_AUTO_CREATE, automatically created.2. Source Code Analysis(1) In the Service subclass, implement the IBinder class by inheriting the Binder and declare an IBinder object; (2) When a visitor binds the Service, the Service uses onBind () (3) In the visitor subclass, when the visitor successfully connects to the Service, the onServiceConnected (ComponentName, IBinder service) of the ServiceConnection object is called back) method to obtain the MyBinder object returned by the onBind method of the Service. The IBinder object can access the Service status data, that is, the value of count.3. Source Code practice(1)/com/exanple/android_service_bind/BindService. java: implements a Service subclass, and then implements an IBinder internal class and a thread.
Package com. example. android_service_bind; import android. app. service; import android. content. intent; import android. OS. binder; import android. OS. IBinder; public class BindService extends Service {private int count; private boolean quit; private MyIBinder binder = new MyIBinder (); // declare an IBinder object // 1. defines an IBinder subclass and implements a public class MyIBinder extends Binder {public int getCount () {r method to obtain the Service running status (count) Eturn count; // return Service running status: count }}// 2. A class that must be implemented by the Service subclass to return the IBinder object public IBinder onBind (Intent intent) {System. out. println ("Service is Binded! "); Return binder; // return IBinder object} // 3. the method @ Override public void onCreate () {super. onCreate (); System. out. println ("Service is Created. "); // create and start a Thread to dynamically modify the count status value new Thread () {@ Override public void run () {while (! Quit) // identifies the disabled startup status of the Service {try {Thread. sleep (1000);} catch (InterruptedException e) {}count ++ ;}}}. start ();} // 4. callback method @ Override public boolean onUnbind (Intent intent) {System. out. println ("Service is Unbinded"); return true;} // 5. call back this method @ Override public void onDestroy () {super. onDestroy (); this. quit = true; // after this method is called (! Quit) is false, and the thread ends System. out. println ("Service is Destroy ");}}
(2) AndroidManifest. xml implementation: configure a Service component for the Service subclass and configure action for the intent-filter of the Service component
<? Xml version = "1.0" encoding = "UTF-8"?> <Manifest xmlns: android = "http://schemas.android.com/apk/res/android" package = "com. example. android_service_bind "android: versionCode =" 1 "android: versionName =" 1.0 "> <uses-sdk android: minSdkVersion =" 8 "android: targetSdkVersion = "19"/> <application android: allowBackup = "true" android: icon = "@ drawable/ic_launcher" android: label = "@ string/app_name" android: theme = "@ style/AppTheme"> <activity android: name =". BindServiceTest "android: label =" @ string/app_name "> <intent-filter> <action android: name =" android. intent. action. MAIN "/> <category android: name =" android. intent. category. LAUNCHER "/> </intent-filter> </activity> <! -- Configure a Service component --> <service android: name = ". BindService"> <intent-filter> <! -- Configure action for the intent-filter of the Service component --> <action android: name = "com. example. service. BIND_SERVICE "/> </intent-filter> </service> </application> </manifest>
(3)/com/exanple/android_service_bind/BindServiceTest. java Implementation: defines a ServiceConnection object, obtains the IBinder object returned by the Service through the onServiceConnected () method of the object, and starts and binds the specified Service through the Intent object.
Package com. example. android_service_bind; import android. app. activity; import android. app. service; import android. content. componentName; import android. content. intent; import android. content. serviceConnection; import android. OS. bundle; import android. OS. IBinder; import android. view. view; import android. view. view. onClickListener; import android. widget. button; import android. widget. toast; public class BindServiceTest extends Activity {Button bind, unbind, status; // 1. keep the IBinder object BindService of the started Service. myIBinder binder; // 2. define a ServiceConnection object private ServiceConnection conn = new ServiceConnection () {//. this method is called back when the Activity and Service are connected successfully @ Override public void onServiceConnected (ComponentName, IBinder service) {System. out. println ("--- Service is connected ---"); // gets the binder object binder = (BindService. myIBinder) service;} // B. when the Activity fails to connect to the Service, the method @ Override public void onServiceDisconnected (ComponentName name) {System. out. println ("--- Service is Disconnected ---") ;};@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); //. obtain the start, stop, and getServiceStatus buttons bind = (Button) findViewById (R. id. bind); unbind = (Button) findViewById (R. id. unbind); status = (Button) findViewById (R. id. getServiceStatus); // B. create Intent final Intent intent = new Intent (); intent. setAction ("com. example. service. BIND_SERVICE "); // c. bind the specified Service. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {bindService (intent, conn, Service. BIND_AUTO_CREATE) ;}}); // d. unbind Service unbind. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {unbindService (conn) ;}}); // e. obtains the Service status and displays the count value of the Service. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {Toast. makeText (BindServiceTest. this, "The count value of Service is:" + binder. getCount (), Toast. LENGTH_SHORT ). show ();}});}}
(4) main Interface layout/res/layout/main. xml
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: orientation = "vertical" android: layout_width = "match_parent" android: layout_height = "match_parent"> <LinearLayout android: orientation = "horizontal" android: layout_width = "match_parent" android: layout_height = "match_parent"> <Button android: id = "@ + id/bind" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_weight = "1" android: text = "binding service"/> <Button android: id = "@ + id/unbind" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_weight = "1" android: text = "Unbind"/> <Button android: id = "@ + id/getServiceStatus" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_weight = "1" android: text = ""/> </LinearLayout>
Demo: (1) When you click bind Service, the visitor calls the bindService () method to start and bind the specified Service. Observe the LogCat of DDMS:
(2) When you click to get the Service status, the visitor calls the getCount () method of MyIBinder in the Service to get the count value through the IBinder object binder;
(3) After clicking unbind, when a visitor unbinds a Service through the unbindService (ServiceConnection conn) method, the system will first call back the onUnbind () method of the Service, then the onDestroy () method is called back, and the Service is disabled.
Note: here the so-called Service status is actually a thread running in the Service to accumulate the count value (implemented in the onCreate () method of the Service ). After a visitor calls the bindService () method to start and bind the Service, the thread starts to run and the count keeps accumulating 1 until the visitor unbinds the Service. Sublimation Note: About IBinder objects? The IBinder object is equivalent to the internal hook of the Service component. This hook is associated with the bound Service component. When other program components are bound to the Service, the Service subclass will return the IBinder object to other program components. Other program components can communicate with the Service component in real time through the IBinder object. Birth: The Service uses the method inheriting the Binder (IBinder implementation class) to implement its own IBinder object. The IBinder onBinder (Intent intent) method provided by the Service returns the IBinder object, destination: when other program components call the onServiceConnected (ComponentName, IBinder service) method of the ServiceConnection object, the IBinder object returned by the Service component is passed in, thus, communication between other program components and the bound Service is realized.
Reference: http://wear.techbrood.com/reference/android/app/Service.html