Android进程间通信之使用Messenger

小近 发布于 2014/11/14 17:43
阅读 260
收藏 9

Messenger,信使,可使用它进行进程间的通信,而MessengerService的请求采用队列的方式,因此它不支持多线程通信。

 

看看官方文档对于Messenger的解释:

 

Reference to a Handler, which others can use to send messages to it. This allows for the implementation of

message-based communication across processes, by creating a Messenger pointing to a Handler in one process,

and handing that Messenger to another process.

客户端和服务端可相互持有对方的Messenger来进行通信,下面我们来看看具体的实现。

在eclipse下创建两个工程,分别为客户端和服务端:

客户端的实现,创建客户端的Messenger,使用Messenger的构造方法指向一个handler实例,此handler用于处理服务端发过来的消息。

而客户端通过onServiceConnected获得服务端的Messenger,使用此Messenger给服务端发送消息,客户端的Messenger通过Message的replyTo传递给服务端。

01. public class MainActivity extends Activity {
02. private static final String TAG = "--DEBUG--";
03. // 用于启动service的ACTION
04. private static final String START_SERVER_ACTION = "com.young.server.START_SERVICE";
05. private static final int WHAT_ON_TO_SERVICE = 1;
06. private static final int WHAT_ON_TO_CLIENT = 2;
07. private Button mBindBtn;
08. private boolean isBindService = false;
09. @Override
10. protected void onCreate(Bundle savedInstanceState) {
11. super.onCreate(savedInstanceState);
12. setContentView(R.layout.activity_main);
13. mBindBtn = (Button) findViewById(R.id.bind_service);
14. mBindBtn.setOnClickListener(new OnClickListener() {
15. @Override
16. public void onClick(View v) {
17. bindService(new Intent(START_SERVER_ACTION), conn, Context.BIND_AUTO_CREATE);
18. }
19. });
20. }
21. // client端Handler,用于处理server端发来的消息
22. private Handler mClientHandler = new Handler(new Callback() {
23. @Override
24. public boolean handleMessage(Message msg) {
25. switch (msg.what) {
26. case WHAT_ON_TO_CLIENT:
27. Log.v(TAG, "客户端收到服务端发来的消息!");
28. break;
29. default:
30. break;
31. }
32. return false;
33. }
34. });
35. // client端Messenger
36. private Messenger mClientMessenger = new Messenger(mClientHandler);
37. private ServiceConnection conn = new ServiceConnection() {
38. @Override
39. public void onServiceDisconnected(ComponentName name) {
40. Log.v(TAG, "服务已断开");
41. isBindService = false;
42. mClientMessenger = null;
43. }
44. @Override
45. public void onServiceConnected(ComponentName name, IBinder service) {
46. Log.v(TAG, "服务已链接");
47. isBindService = true;
48. // 获得server端信使Messenger实例
49. Messenger serverMessenger = new Messenger(service);
50. // 向server端发送的消息
51. Message toServerMessage = Message.obtain(null, WHAT_ON_TO_SERVICE);
52. // 通过replyTo把client端的信使传递给service
53. toServerMessage.replyTo = mClientMessenger;
54. try {
55. serverMessenger.send(toServerMessage);
56. } catch (RemoteException e) {
57. e.printStackTrace();
58. }
59. }
60. };
61. protected void onStop() {
62. if (isBindService)
63. unbindService(conn);
64. super.onStop();
65. };
66. }

 

 

服务端Service的实现,服务端接收到客户端的消息以后,通过Message的replyTo取出客户端的Messenger,使用此Messenger给客户端发送消息,这就实现了进程之间的双向通信。

服务端通过Messenger的getBinder方法将IBinder对象返给客户端,用于共享服务端的Messenger。

01. public class RemoteService extends Service {
02. private static final String TAG = "--DEBUG--";
03. private static final int WHAT_ON_TO_SERVICE = 1;
04. private static final int WHAT_ON_TO_CLIENT = 2;
05. // server端handler,用来处理client发来的消息
06. private Handler mServerHandler = new Handler(new Callback() {
07. @Override
08. public boolean handleMessage(Message msg) {
09. switch (msg.what) {
10. case WHAT_ON_TO_SERVICE:
11. Log.v(TAG, "收到客户端发来的消息");
12. // server端获得client端的信使Messenger
13. Messenger clientMessenger = msg.replyTo;
14. Message toClientMsg = Message.obtain(null, WHAT_ON_TO_CLIENT);
15. try {
16. // 使用客户端Messenger向客户端发送消息
17. clientMessenger.send(toClientMsg);
18. } catch (RemoteException e) {
19. e.printStackTrace();
20. }
21. break;
22. default:
23. break;
24. }
25. return false;
26. }
27. });
28. // server端信使Messenger
29. private Messenger mServerMessenger = new Messenger(mServerHandler);
30. @Override
31. public IBinder onBind(Intent intent) {
32. return mServerMessenger.getBinder();
33. }

 

再来看看服务端service的声明,因为要在其他进程中启动service,所以设置android:exported为true,此外还为service加入启动了权限。

01. <permission android:protectionLevel="normal" android:name="young.permission.START_SERVICE"></permission>
02.  
03. <service
04. android:name="com.young.server.RemoteService"
05. android:permission="young.permission.START_SERVICE"
06. android:exported="true" >
07. <intent-filter>
08. <action android:name="com.young.server.START_SERVICE" />
09. </intent-filter>
10. </service>

最后要在客户端添加相应的启动Service权限。

1. <uses-permission android:name="young.permission.START_SERVICE" />

程序运行后的结果,可以看到客户端和服务端都收到了对方发来的消息。

加载中
返回顶部
顶部