AIDL的全称是 Android Interface Definition Language安卓借口定义语言,安卓定义的进程间通信协议,是安卓进程间通信最常用的方式之一。
1、接口和对象的定义
AIDL使用过程中需要定义需要的接口文件,使用Eclipse开发时,通过写.aidl(AIDL接口描述文件)文件,可以在gen目录下自动生成.java文件:
.aidl文件格式如下:
pacakge .aidl文件所在包名
import 包名+类名(如果使用到Parcable类型的对象,需要引入;基本数据类型,ListMap除外,如果自定义Object对象,需要实现Parcable接口)
interface 接口名{
方法
}
例如:
package com.aidldemo_service.service;
import android.location.Location;
import com.aidldemo_service.domain.User;
interface IDemoService{
Location getCurLocation();
User getUser();
}
**注:接口名需要同.aidl文件的名字一样
.aidl文件写完之后,会在根目录下生成一个.java文件,这个java文件才是我们进行AIDL通信时,需要用到的类,编写.aidl文件只是为了生成这个.java文件
**
在接口定义文档中,需要使用到的自定义Object对象的声明方式:
1、需要定义一个自定义对象的.aidl文件,如:User.aidl
2、自定义对象的.aidl文件格式如下:
package 包名
parcable 类名
例如:
package com.aidldemo_service.domain;
parcelable User;
注:定义好的接口和自定义对象的.java文件,需要通信双方各备一份(.aidl文件也可以双方各备一份或者删除)
2、服务端实现接口
定义好AIDL接口之后,具体的实现是在接口文件中的抽象内部类Stub,它继承了androi.os.Binderj,并实现了接口,我们在服务端创建Stub的对象,完成接口中方法的具体实现
,当客户端启动或者绑定服务端服务的时候,将创建的Stub对象返回,客户端拿到Stub对象之后,就可以直接通过Stub对象,调用方法,例如:
package com.lwang.aidldemo_service.service;
public class ServiceProvider extends Service {
private RemoteServiceHandle mRemoteService;
private LocationManager locationManager;
private String locationProvider;
private String TAG="ServiceDemoTrace";
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
return new RemoteServiceHandle();
}
class RemoteServiceHandle extends IDemoService.Stub{
@Override
public Location getCurLocation() throws RemoteException {
//获取Location
Location location = locationManager.getLastKnownLocation(locationProvider);
return location;
}
@Override
public User getUser() throws RemoteException {
User user = new User();
user.setName("user1");
return user;
}
}
}
2、客户端调用服务
客户端进程通过服务端Service的Action,来调用服务,例如:
public class MainActivity extends Activity {
protected String TAG= "ClientDemoTrace";
private IDemoService mRemoteService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mRemoteService = IDemoService.Stub.asInterface(service);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService();
Button btn = (Button) findViewById(R.id.button01);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Location location = mRemoteService.getLocation();
Log.i(TAG, "location = "+(location==null?"null":location.toString()));
User user = mRemoteService.getUser();
Log.i(TAG, "user = "+user.toString());
}
});
}
private static final String SERVICE_ACTION = "com.demo.Service_Action";
private void bindService(){
Intent intent = new Intent(SERVICE_ACTION);
decorateIntent(intent);//5.0系统之后,不允许通过隐式调用启动服务,调用这个方法,可以达到隐式调用的目的
bindService(intent, conn, 0);
}
private void decorateIntent(Intent intent){
PackageManager pm = getPackageManager();
List<ResolveInfo> resolve = pm.queryIntentServices(intent, 0);
if(resolve==null||resolve.size()==0){
return ;
}
ResolveInfo info = resolve.get(0);
String pacakgeName = info.serviceInfo.packageName;
String name = info.serviceInfo.name;
ComponentName cn = new ComponentName(pacakgeName, name);
intent.setComponent(cn);
}
}