同一进程的通信直接使用Binder对象即可。此时服务端运行在调用他的线程上(如果是主线程调用,有可能造成ANR。ANR:安卓没有回应的英文缩写,就是平常说的app好卡)
不同进程A、B之间的通信,由于A进程无法访问B进程的资源,因此若A进程调用B的binder对象的方法将会访问B的资源,从而内存越界。采用消息机制或AIDL解决。
Messager:
方法要点:把服务端和客户端的Messager(含有handler)暴露给对方,通过其send方法发送信息。客户端需要把自己的Messager放到Message.replyTo中,服务端需要把返回的Binder改成Messager.getBinder()
服务端:
1.把handler包装至自己的Messager对象,返回Binder对象时调用Messager.getBinder()。(暴露自己的Messager给对方)
2.handler重写的handleMessage方法中,可以通过Message.replyTo获取客户端的Messager对象。
3.服务端通过获取到的客户端的Messager.send(Message),去发送信息给客户端
客户端:
1.在ServiceConnection重写的onServiceConnected方法中,通过Messager s=new Messager(service)
把代表服务端的Binder对象换回Messager对象
2.把handler包装至自己的Messager对象。在s.send(message)
(往服务端发送信息)之前,要message.replyTo=Messager对象
来包装信息。(暴露自己的Messager给对方)
具体跟使用handler来线程通信的流程差不多,变了开始流程和增加一些约定而已。
注意:上面的描述看清是 Messager 还是 Message。服务端handleMessage()不会造成客户端的ANR。
AIDL:
如果服务进程不打算以多线程形式与多个进程通信,无需使用这个。
方法要点:按规范书写aidl,android studio自动转换成复杂的接口。按规范重写内部类的方法,把该接口当作Binder子类使用就是。
视oneway关键字,不明确会不会造成客户端的ANR。
网友评论