一、适用场景:
在Android系统开发中,需要监听按键、触摸、或者可见窗口大小变化等需求时,你会考虑什么方法来实现呢?通过广播的方式可以实现,但是效果可能并不好。AIDL可以实现跨进程通讯,可以解决以上需求。下面重点分析下如何具体实现,以实现按键监听功能为例,代码按实现后的调用先后来说明。
二、代码说明以及分析实现:
大致的流程图如下
1、在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java文件中添加监听接口。在interceptKeyBeforeDispatching()方法中获取event传递给自定义监听类SxListenerManager中。
@Override
public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
int policyFlags) {
*****
*****
if (mSystemBooted) {
//SxListenerManager使用单例,使用前判断是否为null
if(SxListenerManager.getInstance() != null) {
//通过系统原生接口截取event事件,传递给自定义SxListenerManager
boolean status = SxListenerManager.getInstance().postKeyEventToUser(event);
if(status){
return -1;
}
}
}
*****
*****
}
2、SxListenerManager.java类主要用于绑定service和定义接口。IBinder.DeathRecipient用于检测远程对象是否存活,由于服务端经常意外停止,我们需要重启service,可以使用linkToDeath
机制。
public class SxListenerManager {
private final static String TAG = "SxListenerManager";
private static SxListenerManager mInstance = null;
private static ISxInputListener mSxListenerService;
private SxListenerManager() {
bindSxListenerService();
}
public static SxListenerManager getInstance() {
if (mInstance == null) {
synchronized (SxListenerManager.class) {
if (mInstance == null) {
mInstance = new SxListenerManager();
}
}
}
return mInstance;
}
private static void bindSxListenerService() {
IBinder service = ServiceManager.getService("Sx_service");
try {
mSxListenerService = ISxService.Stub.asInterface(service).getListener();
service.linkToDeath(deathRecipient, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private static IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
Log.e("SxListenerManager", "=&