服务(Service)是android系统中非常重要的组件。Service可以脱离应用程序运行。也就是说,应用程序只起到一个启动Service的作用。一但Service被启动,就算应用程序关闭,Service仍然会在后台运行。
android系统中的Service主要有两个作用:后台运行和跨进程通讯。后台运行就不用说了,当Service启动后,就可以在Service对象中 运行相应的业务代码,而这一切用户并不会察觉。而跨进程通讯是这一节的主题。如果想让应用程序可以跨进程通讯,就要使用我们这节讲的AIDL服 务,AIDL的全称是Android Interface Definition Language,也就是说,AIDL实际上是一种接口定义语言。通过这种语言定义接口后,Eclipse插件(ODT)会自动生成相应的Java代码接 口代码。下面来看一下编写一个AIDL服务的基本步骤。
1.在Eclipse工程的package目录中建立一个扩展名为aidl的文件。package目录就是Java类所在的目录。该文件的语法类似于Java代码。aidl文件中定义的是AIDL服务的接口。这个接口需要在调用AIDL服务的程序中访问。
2.如果aidl文件的内容是正确的,Eclipse插件会自动生成一个Java接口文件(*.java)。
3.建立一个服务类(Service的子类)。
4.实现由aidl文件生成的Java接口。
5.在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签的android:name属性值就是客户端要引用该服务的ID,也就是Intent类构造方法的参数值。
现在我们来编写一个AIDL服务,首先建立一个android工程:aidlservice。在aidlservice工程中有一个Main类,在Main类所有的目录建立一个IMyService.aidl文件,内容如下:
package net.blogjava.mobile.aidlservice; interface IMyService { String getValue(); // 为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法 }
在保存IMyService.aidl文件后,ODT会在gen目录下产生一个IMyService.java文件,读者可以不必管这个文件中的内容,也 不需要修改该文件的内容。这个文件是由ODT自动维护的,只要修改了IMyService.aidl文件的内容,IMyService.java文件的内 容就会随之改变。
然后建立一个MyService类,该类是Service的子类,代码如下:
public class MyService extends Service { //IMyService.Stub类是根据IMyService.aidl文件生成的类,该类中包含了接口方法(getValue) public class MyServiceImpl extends IMyService.Stub { @Override public String getValue() throws RemoteException { return "从AIDL服务获得的值."; } } @Override public IBinder onBind(Intent intent) { //该方法必须返回MyServiceImpl类的对象实例 return new MyServiceImpl(); } }
最后需要在AndroidManifest.xml文件中配置MyService类,代码如下:
<!-- 注册服务 --> <service android:name=".MyService"> <intent-filter> <!-- 指定调用AIDL服务的ID --> <action android:name="net.blogjava.mobile.aidlservice.IMyService" /> </intent-filter> </service>
下面来看看如何调用这个AIDL服务。首先建立一个android工程:aidlclient。然后将aidlservice工程中自动生成的 IMyService.java文件复制到aidlclient工程中。在调用AIDL服务之前需要先使用bindService方法绑定AIDL服务。 bindService方法需要一个ServiceConnection对象。ServiceConnection有一个 onServiceConnected方法,当成功绑定AIDL服务且,该方法被调用。并通过service参数返回AIDL服务对象。下面是调用 AIDL服务的完成代码。
public class Main extends Activity implements OnClickListener { private IMyService myService = null; // 创建ServiceConnection对象 private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 获得AIDL服务对象 myService = IMyService.Stub.asInterface(service); try { // 调用AIDL服务对象中的getValue方法,并以对话框中显示该方法的返回值 new AlertDialog.Builder(Main.this).setMessage(myService.getValue()).setPositiveButton("确定", null).show(); } catch (Exception e) { } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override public void onClick(View view) { // 绑定AIDL服务 bindService(new Intent("net.blogjava.mobile.aidlservice.IMyService"), serviceConnection, Context.BIND_AUTO_CREATE); } }
在编写AIDL服务和客户端时要注意如下两点:
1. AIDL服务中的onBind方法必须返回AIDL接口对象(MyServiceImpl对象)。该对象也是onServiceConnected事件方法的第2个参数值。
2. bindService方法的第1个参数是Intent对象,该对象构造方法的参数需要指定AIDL服务的ID,也就是在 AndroidManifest.xml文件中<service>标签的<action>子标签的android:name属性 的值。
现在先运行aidlservice程序,以便安装AIDL服务,然后运行aidlclient程序,并单击按钮,会显示如图11所示的对话框。对话框中的信息就是AIDL服务接口中getValue方法的返回值。
原文地址:https://www.cnblogs.com/chenxibobo/p/9648835.html