码迷,mamicode.com
首页 > 移动开发 > 详细

Android进阶笔记04:Android进程间通讯之Messenger ( 区别于AIDL)

时间:2015-10-12 21:08:07      阅读:335      评论:0      收藏:0      [点我收藏+]

标签:

一、 Android进程间通讯之Messenger 的引入

(1)引言

     平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进程间通讯。它是基于消息的进程间通信,就像子线程和UI线程发送消息那样,是不是很简单,还不用去写AIDL文件,是不是有点小爽。哈哈。此外,还支持记录客户端对象的Messenger,然后可以实现一对多的通信;甚至作为一个转接处,任意两个进程都能通过服务端进行通信。

(2) Messenger 与 AIDL 比较:

      当您需要执行 IPC 时,为您的接口使用 Messenger 要比使用 AIDL 实现更加简单,因为 Messenger 会将所有服务调用排入队列,而纯粹的 AIDL 接口会同时向服务发送多个请求,服务随后必须应对多线程处理。

  对于大多数应用,服务不需要执行多线程处理,因此使用 Messenger 可让服务一次处理一个调用。如果您的服务必须执行多线程处理,则应使用 AIDL 来定义接口。

 

二、  Messenger 的具体使用:

1. 客户端发送消息给服务端(单向通信)

服务端

  (1)创建一个handler对象,并实现hanlemessage方法,用于接收来自客户端的消息,并作处理 .

  (2)创建一个messenger(送信人),封装handler .

  (3)messenger创建一个IBinder对象,通过onBind返回给客户端

客户端

  (1)在activity中绑定服务

  (2)创建ServiceConnection并在其中使用 IBinder 将 Messenger实例化 

  (3)使用Messenger向服务端发送消息

  (4)解绑服务

  (5)服务端中在 handleMessage() 方法中接收每个 Message

这样,客户端并没有调用服务的"方法"。而客户端传递的"消息"(Message 对象)是服务在其 Handler 中接收的。

上面实现的仅仅是单向通信,即客户端给服务端发送消息

 

 

2. 客户端与服务端双向通信

如果我需要服务端给客户端发送消息又该怎样做呢?

其实,这也是很容易实现的,下面就让我们接着上面的步骤来实现双向通信吧:

  (1)在客户端中创建一个Handler对象,用于处理服务端发过来的消息。

  (2)创建一个客户端自己的messenger对象,并封装handler。

  (3)将客户端的Messenger对象赋给待发送的Message对象的replyTo字段。

  (4)在服务端的Handler处理Message时将客户端的Messenger解析出来,并使用客户端的Messenger对象给客户端发送消息。

这样就实现了客户端和服务端的双向通信了。

注意:

  注:Service在声明时必须对外开放,即android:exported="true"

    是不是看的头晕,忘掉吧,直接看下面

 

三、代码示例:

(1)服务端service:

 1 public class MyService extends Service {
 2     private static final int CODE = 1;
 3     public MyService() {
 4     }
 5     @Override
 6     public IBinder onBind(Intent intent) {
 7         return mMessenger.getBinder();
 8     }
 9 
10     //创建一个送信人,封装handler
11     private Messenger mMessenger = new Messenger(new Handler() {
12         @Override
13         public void handleMessage(Message msg) {
14             Message toClient = Message.obtain();
15             switch (msg.what) {
16                 case CODE:
17                     //接收来自客户端的消息,并作处理
18                     int arg = msg.arg1;
19                     Toast.makeText(getApplicationContext(),arg+"" , Toast.LENGTH_SHORT).show();
20                     toClient.arg1 = 1111111111;
21                     try {
22                         //回复客户端消息
23                         msg.replyTo.send(toClient);
24                     } catch (RemoteException e) {
25                         e.printStackTrace();
26                     }
27             }
28             super.handleMessage(msg);
29         }
30     });
31 }

 

(2)客户端

 1 package com.zixue.god.fuck;
 2 
 3 import android.content.ComponentName;
 4 import android.content.Intent;
 5 import android.content.ServiceConnection;
 6 import android.os.Bundle;
 7 import android.os.Handler;
 8 import android.os.IBinder;
 9 import android.os.Message;
10 import android.os.Messenger;
11 import android.os.RemoteException;
12 import android.support.v7.app.AppCompatActivity;
13 import android.util.Log;
14 import android.view.View;
15 import android.widget.Button;
16 import android.widget.Toast;
17 
18 public class MainActivity extends AppCompatActivity {
19     private boolean mBond;
20     private Messenger serverMessenger;
21     private MyConn conn;
22 
23     @Override
24     protected void onCreate(Bundle savedInstanceState) {
25         super.onCreate(savedInstanceState);
26         setContentView(R.layout.activity_main);
27         //绑定服务
28         Intent intent = new Intent();
29         intent.setAction("com.zixue.god.myapplication.server");
30         conn = new MyConn();
31         bindService(intent, conn, BIND_AUTO_CREATE);
32         Button button = (Button) findViewById(R.id.bt);
33         button.setOnClickListener(new View.OnClickListener() {
34             @Override
35             public void onClick(View v) {
36                 Message clientMessage = Message.obtain();
37                 clientMessage.what = 1;
38                 clientMessage.arg1 = 12345;
39                 try {
40                     clientMessage.replyTo = mMessenger;
41                     serverMessenger.send(clientMessage);
42                 } catch (RemoteException e) {
43                     e.printStackTrace();
44                 }
45             }
46         });
47     }
48 
49     private class MyConn implements ServiceConnection {
50 
51         @Override
52         public void onServiceConnected(ComponentName name, IBinder service) {
53             //连接成功
54             serverMessenger = new Messenger(service);
55             Log.i("Main", "服务连接成功");
56             mBond = true;
57         }
58 
59         @Override
60         public void onServiceDisconnected(ComponentName name) {
61             serverMessenger = null;
62             mBond = false;
63         }
64     }
65     private Messenger mMessenger = new Messenger(new Handler(){
66         @Override
67         public void handleMessage(Message msg) {
68             Toast.makeText(getApplicationContext(),msg.arg1+"",Toast.LENGTH_SHORT).show();
69             super.handleMessage(msg);
70         }
71     });
72     @Override
73     protected void onDestroy() {
74         if (mBond) {
75             unbindService(conn);
76         }
77         super.onDestroy();
78     }
79 
80 }

 

Android进阶笔记04:Android进程间通讯之Messenger ( 区别于AIDL)

标签:

原文地址:http://www.cnblogs.com/hebao0514/p/4872754.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!