天天看点

Android跨进程访问-Service跨进程访问(AIDL服务)

前言:

服务(Service)是Android四大组件之一,它可以脱离应用程序在后台运行,另服务也可以进行跨进程通讯。要想实现服务跨进程,就要用到AIDL服务,AIDL的全称是Android Interface Definition Language,也就是说,AIDL实际上是一种接口定义语言。通过这种语言定义接口后,Eclipse插件(ODT)会自动生成相应的Java接口代码。

一、创建AIDL服务

1、在Eclipse工程的package目录下,创建一个扩展名为aidl的文件,该文件的语法类似于Java代码。aidl文件中定义的是AIDL服务的接口。这个接口需要在调用AIDL服务的程序中访问。该文件编写正确后,会在gen目录下自动生成一个.java文件。aidl文件内容如下:

package com.sarnasea.aidl;
interface IMyService{

	/**
	 * 为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法
	 * @return {@link String}
	 */
    String getValue();
}
           

2、实现AIDL文件生成的JAVA接口,示例代码如下:

class MyServiceImpl extends IMyService.Stub{

	@Override
	public String getValue() throws RemoteException {
		
		return "从AIDL服务获取的值";
	}
}
           

3、创建一个服务类,将接口暴露给客户端调用。示例代码如下:

/**
 * @class description 远程服务供客户端调用
 */
public class RemoteService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		
		return new MyServiceImpl();
	}
}
           

4、在AndroidManifest.xml文件中申明服务,指定其Action。示例代码如下:

<service android:name="com.sarnasea.aidl.RemoteService">
            <intent-filter>
                <action android:name="com.sarnasea.aidl.IMyService"/>
			</intent-filter>
        </service>
           

这样,AIDL服务就创建完成了,接下来就要实现客户端调用AIDL服务.....

二、调用AIDL服务

在新的应用中可以调用上面创建的AIDL服务。首先需要将之前在gen目录下自动生成的IMyService.java文件复制到新的目录。然后在Activity中调用bindService方法绑定服务,示例代码如下:

//点击远程调用服务按钮
		case R.id.invoke_remote_service_btn:
						
			Intent serviceIntent = new Intent();
			// 设置Intent Action 属性
			serviceIntent.setAction("com.sarnasea.aidl.IMyService");
			// 绑定服务
			bindService(serviceIntent, serviceConn, Service.BIND_AUTO_CREATE);
			break;
           

其中绑定服务方法中参数serviceConn为ServiceConnection对象,当成功绑定AIDL服务,onServiceConnected方法被调用。并通过service参数返回AIDL服务对象,然后便可对AIDL服务对象进行操作,示例代码如下:

// 绑定服务连接监听接口
		serviceConn = new ServiceConnection() {

			@Override
			public void onServiceDisconnected(ComponentName name) {

				Toast.makeText(MainActivity.this, "远程服务绑定失败",
						Toast.LENGTH_SHORT).show();
			}

			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {

				// 绑定成功
				IMyService myService = IMyService.Stub.asInterface(service);
				try {
					String value = myService.getValue();
					Toast.makeText(MainActivity.this, value, Toast.LENGTH_SHORT)
							.show();
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		};
           

注意:

1.  AIDL服务中的onBind方法必须返回AIDL接口对象(MyServiceImpl对象)。该对象也是onServiceConnected事件方法的第2个参数值。

2.  bindService方法的第1个参数是Intent对象,该对象构造方法的参数需要指定AIDL服务的ID,也就是在 AndroidManifest.xml文件中<service>标签的<action>子标签的android:name属性的值。