3.AIDL
Android Interface Definition Language:接口描述语言
-----------------------------------------------
跨进程调用Service实例
步骤:
1.在客户端创建接口,比如名字叫 IPlayController
安卓系统会自动生成类 Stub
extends Binder
implements IPlayController。
类型转换的方法 IPlayController
asInterface (IBinder obj)
2.在客户端编写MyService类
MyService的内部类MyBinder继承自Stub类。
其中特别需要注意的是:onBind方法需要返回MyBinder实例。
3.在服务端,同样将接口拷贝过来,IPlayController
4.在服务端的Activity中绑定MyService,并创建获取ServiceConnection的实例,当绑定成功的时候
会回调其onServiceConnection,将传入的参数IBinder实例转换为IPlayController实例。就可以远程调用service的服务方法了
如:
private IPlayController icontroller;
ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
//获取到controller对象
icontroller=IPlayController.Stub.asInterface(binder);
}
};
bindService(intent, conn, BIND_AUTO_CREATE);
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
4.AIDL应用:电话,ITelephony
接口:ITelephony.aidl
基本逻辑:参考6.ServiceManager
监听电话应用-拦截电话:
1.拷贝iTelephony.aidl接口
2.获得ITelephony:TelePhonyManager类中有一个私有方法。
private
ITelephony
getITelephony() {
return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
},利用java 的反射机制
如果能或取到ServiceManager类,可以使用正常做法。但是Android的设计将ServiceManager隐藏了,所以只能使用反射机制。
正常做法:
IBinder binder=ServiceManager.getService(TELEPHONY_SERVICE);
ITelephony tel=ITelephony.Stub.asInterface(binder);
tel.endCall();
反射代码:
//获得ServiceManager的类对象,然后获得其方法对象
Method method=Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", String.class);
IBinder binder=(IBinder)method.invoke(null, TELEPHONY_SERVICE)//对于静态方法,第一个参数可以被忽略,即可以将它设置为null
ITelephony tel=ITelephony.Stub.asInterface(binder);//IBinder类型转换为ITelephony类型实例
tel.endCall();