四大组件_Service_AIDL_2

2017-07-12  本文已影响12人  VelyVelyGood

1、AIDL 服务端和客户端通信的方法:

    AIDL服务端调用客户端方法,可以用客户端注册 AIDL 类型接口的方式实现(aidl接口.Stub() 实现,即生成的对象是 Binder 对象);如图

在客服的实现的 aidl 回调接口

2、AIDL 跨进程接口注册和解除注册的问题:

服务端用 map 或 RemoteCallBackList 保持注册的对象;

    2.1、用 RemoteCallBackList 好处:

客户端进程终止后,可以自动移除客户端注册的 Listener;

内部实现了线程同步,所以用它注册和解除注册时不用额外的做线程同步工作

2.2、原理是 RemoteCallBackList 中 key 、value 分别为

IBinder key = listener.asBinder();

CallBack value = new CallBack(Listener, cookie);

所以:虽然多次跨进程传输客户端的同一个对象会在服务端生成不同的对象,但是这些新生成的对象的底层 Binder 对象是同一个!所以可以用这个 共同的 Binder 对象做 key。

2.3、RemoteCallBackList 遍历

箭头标识了遍历开始和结束需要调用的方法

3、AIDL 可能导致的 ANR 问题

  3.1、客户端调用远程服务方法,被调用方法运行在服务端的 Binder 线程池中,同时客户端线程会被挂起,此时若服务端方法执行比较耗时,会导致客户端线程长时间阻塞在这里,如果这个客户端线程是 UI 线程的话,就会导致客户端 ANR。所以一般不要在客户端 UI 线程中去访问服务端确定耗时的方法。

  3.2、服务端本身就运行在 Binder 线程池中,本身就可以执行大量耗时操作,所以切记不要在服务端方法中开线程去执行异步任务,除非有明确目的。

客户端 onServiceConnected onServiceDisconnected 运行在 UI 线程中,故不可以在里面调用耗时的服务端方法;

同理,远程服务端需要调用客户端的 listener 中的方法是,被调用方法运行在客户端的 Binder 线程池中,所以服务端同样不能 UI 线程中调用客户端的耗时方法

4、服务端意外停止时,客户端重新连接服务逻辑

    4.1、onServieceDisconnected() 回调中重连,该方法运行在 UI 线程中。

    4.2、给 Binder 设置 DeathRecipient 监听,在其回调 binderDied 中重联,该方法运行在非 UI 线程中。

5、AIDL 及 Messager 进行 IPC 通信 设置权限认证

验证用以保护不被 非允许的应用访问 server;

    5.1、验证位置

在服务端的 onBind() 方法中验证,不通过则返回 null。

在服务端的 onTransact 方法中验证, 验证失败返回 false。

    5.2、验证内容

验证自定义 permission ;(补充:自定义 Permission 及使用

验证 Uid 、Pid;

其他验证内容

在 server onTransact 方法中验证 permission 和 UID
上一篇下一篇

猜你喜欢

热点阅读