Android-bind a service to call a service
The Service can be started in two ways:
1. Started
Started Service is Started by using the startService (Intent intent) method in the Application. Once started, this type of Service will run endlessly, even if its Activity is Destroy. To stop a Service of this type, you can call stopSelf () in the Service or call stopService (Intent intent) in the Application ), otherwise, you can only kill the Android system when the system resources are insufficient.
2. Bound
Bound's Service is started by calling the bindService () method in the Application. This type of Service is bound with the Application. Once all the bound applications disappear, Android Detroy the Service. You can also call the unbindService () method to unbind a Service.
Sometimes we want to know the Service status in the Activity. For example, in a music player, the Service is responsible for playing music, and the Activity is responsible for displaying the current song name and playing progress.
You can use Broadcast, which is also a solution.
However, if you can obtain the Service instance, you can call the custom methods of the Service to obtain the Service status.
First, we must make it clear that the first type of Service is powerless. Because there is no associated interface between the Activity and the Service, even if the Service is started in the Activity, once the start, the two are no longer associated.
1. Local Service call.
If Activity and Service are in the same application, the interaction between the two is a local Service call.
You can use bindService to perform the following operations:
1. The custom subclass MyService inherits the Service class.
2. In the MyService class, the custom internal class MyBinder inherits the Binder class
In the internal class, create some methods based on the data that needs to be interacted, so that the Activity can obtain some data in the Service through these methods. Or simply return the Service instance using a method.
public class MyBinder extends Binder { public MyService getServiceInstance() { return MyService.this; } }
3. In the Service class, a new MyBinder private member is added and a MyBinder instance is returned in the onBind () method.
This is because once the Service is bound, the onBind () method is called back and a Binder object is returned to the Activity. For details, refer to the next step.
4. Override the onServiceConnected (ComponentName, IBinder service) method in the ServiceConnection interface in the Activity,
The service parameter is the MyBinder object returned by the onBind () method in the MyService class. Call the custom method getServiceInstance () of the MyBinder object to obtain the Service instance.
The following is a DEMO:
Import android. OS. bundle; import android. OS. IBinder; import android. app. activity; import android. content. componentName; import android. content. intent; import android. content. serviceConnection; import android. view. menu; import android. view. view; public class MainActivity extends Activity {MusicInterface mi; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); Intent intent = new Intent (this, MusicService. class); // mixed call // in order to convert the process of the service into the service process startService (intent); // to obtain the intermediary object bindService (intent, new MusicServiceConn (), BIND_AUTO_CREATE);} class MusicServiceConn implements ServiceConnection {@ Overridepublic void onServiceConnected (ComponentName, IBinder service) {// TODO Auto-generated method stubmi = (MusicInterface) service ;} @ Overridepublic void onServiceDisconnected (ComponentName name) {// TODO Auto-generated method stub} // The start play button public void play (View v) {mi. play () ;}// pause the play button public void pause (View v) {mi. pause ();}}
Import android. app. service; import android. content. intent; import android. OS. binder; import android. OS. IBinder; public class MusicService extends Service {@ Overridepublic IBinder onBind (Intent intent) {// TODO Auto-generated method stubreturn new MusicController () ;}// binder must be inherited, class MusicController extends Binder implements MusicInterface {public void play () {MusicService. this. play ();} public void pause () {MusicService. this. pause () ;}} public void play () {System. out. println ("Play Music");} public void pause () {System. out. println ("pause playback ");}}
public interface MusicInterface {void play();void pause();}
2. Cross-process Service call
A cross-process Service call is called in the current application to call the Service in another application.
In Android, each application runs in its own Process and has an independent Dalvik Virtual Machine instance, which is called Inter-Process Comunication ).
It can be implemented through the AIDL service.
AIDL (Android Interface Definition Language) is a Java-like Language defined by Android. It is mainly used to define the interface between the server and the client for data interaction during cross-process calls.
The AIDL service does not support all Java data types. It only supports the following types:
1. Java simple type (int, char, boolean, etc ). Import not required
2. String and CharSequence. Import not required
3. List and Map. No need to import (it should be noted that the element types of List and Map must be supported by AIDL)
4. APIs automatically generated by AIDL. Import required
5. classes that implement the android. OS. Parcelable interface. Import required
To create a simple AIDL service, follow these steps:
(1) server steps:
1. Create the AIDL file IMyAidl. aidl on the server.
AIDL is similar to Java code. The sample code is as follows: (Note: The suffix of the aidl file is. aidl)
interface IMyAidl{void print();}
After the aidl file is created, the ADT automatically calls the aidl command to generate the corresponding Java file. Check whether there is a file named IMyAidl. java in the gen folder. If not, the. aidl file is incorrect.
2. inherit the Service class and expose the AIDL interface in the subclass.
This step is similar to a local Service call, and an IBinder object is returned through the onBind (Intent intent) method.
The sample code is as follows:
Public class MyService extends Service {private AidlBinder mBinder; // Stub class is in the previous step, A class in the Java code generated by the aidl command // This class implements the IBinder interface and the IMyAidl interface. // You can inherit this class and then in onBind () the AidlBinder object is returned in the method. // you can use the AidlBinder object to call the methods defined in the AIDL file public class AidlBinder extends Stub {@ Overridepublic void print () {System. out. println ("Hello world! ") // Implement the interface functions in the AIDL file }}@ Overridepublic void onCreate () {mBinder = new AidlBinder (); // create a Binder object when starting the service} @ Overridepublic IBinder onBind (Intent intent) {return mBinder; // return the Binder object and obtain the Binder object from the client }}
3. Configure the AndroidManifest. xml file
<!--{cke_protected}{C}%3C!%2D%2D%20%E8%87%AA%E5%AE%9A%E4%B9%89%E8%AE%BF%E9%97%AEService%E6%89%80%E9%9C%80%E7%9A%84%E6%9D%83%E9%99%90%20%2D%2D%3E--><permission android:protectlevel="normal" android:name="thomas.permission.AIDL_SERVICE"><service android:name="com.thomas.aidlserver.MyService" android:exported="true" android:permission="thomas.permission.AIDL_SERVICE"><!--{cke_protected}{C}%3C!%2D%2D%20IntentFilter%E5%B1%9E%E6%80%A7%E6%98%AF%E5%BF%85%E4%B8%8D%E5%8F%AF%E5%B0%91%E7%9A%84%20%2D%2D%3E--><!--{cke_protected}{C}%3C!%2D%2D%20%E5%A6%82%E6%AD%A4%E4%B8%80%E6%9D%A5%EF%BC%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%89%8D%E8%83%BD%E9%80%9A%E8%BF%87%E8%AF%A5action%E8%BF%9C%E7%A8%8B%E8%B0%83%E7%94%A8%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%9A%84Service%20%2D%2D%3E--><intent-filter><action android:name="com.thomas.aidlserver.action.AIDL_SERVICE"></action></intent-filter></service></permission>
(2) Client steps:
1. Create an AIDL File
The client must also create an AIDL file, which is exactly the same as the AIDL file on the server.
Copy the AIDL file on the server. It should be noted that the package name of the AIDL file must be consistent with that of the server.
If the client does not have this package, create a package and put the AIDL file under the package.
2. Cross-process Service calling
The cross-process Service call method of the client is similar to that of the local Service call. It also uses bindService ().
It should be noted that after the call is successful, the Binder object passed by the onServiceConnected (ComponentName, IBinder service) method of the ServiceConnection interface is obtained. You can call the methods defined in this interface by converting the object type to the interface type declared in the AIDL file.
The sample code is as follows:
Private IMyAidl mAidl; mServiceCon = new ServiceConnection () {@ Overridepublic void onServiceConnected (ComponentName, IBinder service) {// convert the IBinder type to the IMyAidl type. MAidl = IMyAidl. stub. asInterface (service) ;}@ Overridepublic void onServiceDisonnected (ComponentName name) {}} // remote Service binding, where the Intent action parameter is the server at // AndroidManifest. xml file
Under the tag
The specified string bindService (new Intent ("com. thomas. aidlserver. action. AIDL_SERVICE "), mServiceCon, Service. BIND_AUTO_CREATE); mAidl. print (); // call the method declared in the AIDL File
3. Configure the AndroidManifest. xml file
<!--{cke_protected}{C}%3C!%2D%2D%20%E8%AF%B7%E6%B1%82%E8%AE%BF%E9%97%AE%E8%BF%9C%E7%A8%8BService%E6%89%80%E9%9C%80%E7%9A%84%E6%9D%83%E9%99%90%EF%BC%8C%E8%AF%A5%E6%9D%83%E9%99%90%E5%AE%9A%E4%B9%89%E4%BA%8E%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%9A%84AndroidManifest.xml%E6%96%87%E4%BB%B6%E4%B8%AD%20%2D%2D%3E--><uses-permission android:name="thomas.permission.AIDL_SERVICE"></uses-permission>