一、AIDL服务简介
Android系统中,各应用程序都运行在自己的进程中,进程之间一般无法直接进行数据交换,我们可以通过AIDL实现跨进程调用Service。
当客户端访问service时,远程Service会通过onBInd()方法将IBinder对象的代理返回给客户端(具体是返回到客户端ServiceConnection的onServiceConnected方法的第二个参数)。当客户端获取了远程Service的IBinder对象的代理之后,就可以通过IBinder对象去回调远程Service的属性和方法了。
二、AIDL服务端
1. 创建AIDL文件
AIDL只是定义两个进程之间的通信接口,其语法与java接口很相似。但存在如下几点差异:
- AIDL定义接口的源代码必须以.aidl结尾。
- AIDL接口中用到的数据类型,除了基本类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即使他们在同一个包中也需要导包。
定义一个AIDL接口:
// IUser.aidl
package com.example1.test.aidl;
// Declare any non-default types here with import statements
interface IUser {
String getName();
int getId();
}
定义好上面的AIDL接口之后,ADT工具在该接口所在包的目录下生成一个IUser.java接口,在该接口里包含一个Stub内部类,该内部类实现了IBinder、IUser两个接口,这个Stub类将会作为远程Service的回调类——它实现了IBinder接口,因此可以作为Service的onBinder()方法的返回值。
2. 将接口暴露给客户端—Service实现类
Service实现类,其中的onBInd()方法返回的IUer.Stub的实例,供其它应用程序的调用并获取service的信息。
public class AIDLService extends Service{
private String name;//用户姓名
private int id;//用户id
public IUser.Stub userBinder=new IUser.Stub() {
@Override
public String getName() throws RemoteException {
name="服务端name";
return name;
}
@Override
public int getId() throws RemoteException {
id=1001;
return id;
}
};
//返回userBinder对象
@Override
public IBinder onBind(Intent intent) {
/**
* 在绑定本地Service的情况下,该userBinder对象会直接传给客户端的
* ServiceConnection对象的onServiceConnected方法的第二个参数
*
* 在绑定远程Service的情况下,只将catBinder对象的代理传给客户端的
* ServiceConnection对象的onServiceConnected方法的第二个参数
*/
return userBinder;
}
}
3. 配置Service
完成上面的之后,我们还需要在AndroidManifest.xml文件中配置该Service。如下所示:
<!--定义一个Service组件-->
<service android:name=".AIDLService">
<intent-filter>
<action android:name="com.example1.test.aidl.AIDLService"/>
</intent-filter>
</service>
三、客户端访问AIDLService
1. 复制AIDL接口
AIDL定义了两个进程之间的通信接口,因此不仅服务器端需要AIDL接口,客户端同样需要前面定义的AIDL接口,我们只需要直接该接口复制到客户端程序中。
2. 客户端绑定远程Service
客户端绑定远程Service只需两步:
- 创建ServiceConnection对象
- 以ServiceConnection对象作为参数,调用Context的bindService()方法绑定远程Service即可。
具体的代码如下所示,布局文件中只是添加了一个Button按钮和一个TextView文本控件,此处不展示。
public class UserInfoActiivity extends AppCompatActivity {
private IUser userBinder;
private ServiceConnection sconn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取远程Service的onBind方法返回的对象的代理
userBinder=IUser.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
userBinder=null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_info_actiivity);
bindRemoteService();//开启远程服务
final TextView tvUserInfo=findViewById(R.id.tvUserInfo);
Button btnGetUserInfo=findViewById(R.id.btnGetUserInfo);
//获取服务端的用户信息
btnGetUserInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
String name=userBinder.getName();
int id=userBinder.getId();
tvUserInfo.setText("姓名:"+name+'\n'+"id:"+id);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
//绑定远程服务
public void bindRemoteService(){
Intent intent=new Intent();
intent.setAction("com.example1.test.aidl.IUser");
ComponentName componentName=new ComponentName("com.example1.test.aidl","com.example1.test.aidl.AIDLService");
intent.setComponent(componentName);
bindService(intent,sconn, Service.BIND_AUTO_CREATE);//绑定远程服务
}
}
四、运行结果
启动客户端和服务端的程序,然后点击客户端的获取用户信息的按钮,效果如下:
![](https://img.haomeiwen.com/i9194875/ed2802255bdc22f6.png)
五、总结
总结下来就是两个部分,服务端定义AIDL接口,然后实现Service,并在AndroidManifest.xml注册服务;客户端复制服务端的AIDL接口,然后绑定远程服务。
网友评论