• Android进程间通信之使用Messenger


    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传递给服务端。

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

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

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

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

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

     1 <permission android:protectionLevel="normal" android:name="young.permission.START_SERVICE"></permission>
     2     
     3 <service
     4     android:name="com.young.server.RemoteService"
     5     android:permission="young.permission.START_SERVICE"
     6     android:exported="true" >
     7     <intent-filter>
     8         <action android:name="com.young.server.START_SERVICE" />
     9     </intent-filter>
    10 </service>

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

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

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

    11-12 12:58:37.197: V/--DEBUG--(21322): 服务已链接
    11-12 12:58:37.197: V/--DEBUG--(21268): 收到客户端发来的消息
    11-12 12:58:37.197: V/--DEBUG--(21322): 客户端收到服务端发来的消息!

     

  • 相关阅读:
    jmeter 安装
    Day05_系统监控、rpm、yum软件包管理及源码安装python解释器
    Day04_vim编辑器及硬盘操作
    Day03_用户群组权限及正文处理命令
    Day02_操作系统、网络及Linux基础
    Day01_计算机硬件及启动流程
    让Sublime Text成为静态WEB服务器:SublimeServer
    sublime text2-text3 定义的不同浏览器的预览快捷键
    css之px自动转rem—“懒人”必备
    修改Sublime Text3 的侧边栏字体大小
  • 原文地址:https://www.cnblogs.com/virtual-young/p/4091955.html
Copyright © 2020-2023  润新知