zoukankan      html  css  js  c++  java
  • Android11_IPC方式之Messenger

    通过Messenger可以在不同的进程中传递Messenger对象;

    Message放入我们需要传递的数据;就可以轻松实现数据的进程间传递;

    Messenger是轻量级的IPC方案;底层实现是AIDL;

    Messenger对AIDL做了封装,使得我们可以简便地进行进程间通信;

    由于其一次处理一个请求,因此在服务端不需要考虑线程同步的问题;

    因为服务端中不存在并发执行的情形;

    1、服务端

    创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messenger对象;

    然后在Service的onBind方法中返回这个Messenger对象底层的Binder即可;

    2、客户端

    首先要绑定服务端Service,绑定成功后用服务端返回的IBinder对象创建一个Messenger,通过这个Messenger对象就可向服务端发送消息了;

    发消息的类型是Message对象,如果需要服务端能够回应客户端,那么也需要创建一个Handler并创建一个新的Messenger,

    并把这个Messenger对象通过Message的replyTo参数传递给服务端;服务端通过这个replyTo参数就可以回应客户端。

    ===================================================

    服务端代码:

     1 package com.example.messengertest_server;
     2 
     3 import android.app.Service;
     4 import android.content.Intent;
     5 import android.os.Bundle;
     6 import android.os.Handler;
     7 import android.os.IBinder;
     8 import android.os.Message;
     9 import android.os.Messenger;
    10 import android.os.RemoteException;
    11 import android.util.Log;
    12 
    13 public class MessengerService extends Service {
    14     private static final String TAG = "Service";
    15     private static final int MSG_OPCODE_1 = 1;
    16 
    17     //定义一个继承自Handler的类
    18     private static class MsgHandler extends  Handler {
    19         @Override
    20         public void handleMessage(Message msg){
    21             super.handleMessage(msg);
    22             switch(msg.what){
    23                 case MSG_OPCODE_1:
    24                     //取出客户端的内容
    25                     Bundle bundle = msg.getData();  //取出bundle
    26                     String clientmsgstr = bundle.getString("client");  //解析bundle
    27                     Log.d(TAG,"Service handle msg with client string:"+clientmsgstr); //打印
    28 
    29                     //新建一个Message,回复客户端
    30                      Message replymsg = Message.obtain();  //创建消息
    31                      replymsg.what = MSG_OPCODE_1;
    32                      Bundle replybundle = new Bundle(); //创建bundle
    33                      replybundle.putString("service","我很好");//往bundle中存放数据
    34                      replymsg.setData(replybundle);//往消息中存放bundle
    35 
    36                     //对收到的msg进行回复
    37                      try{
    38                          msg.replyTo.send(replymsg); //msg.replyTo是客户端携带过来的Messenger对象
    39                      }catch(RemoteException e){
    40                          e.printStackTrace();
    41                      }
    42                      break;
    43                 default:
    44                     break;
    45             }
    46         }
    47     }
    48 
    49     private MsgHandler mHandler = new MsgHandler();
    50     private Messenger mMessenger = new Messenger(mHandler);//创建一个Messenger,将Handler作为参数
    51 
    52 
    53     @Override
    54     public IBinder onBind(Intent intent){
    55         return mMessenger.getBinder();
    56     }
    57 
    58     @Override
    59     public void onCreate(){
    60         super.onCreate();
    61         Log.d(TAG, "onCreate: ");
    62         if(mMessenger == null){
    63             mMessenger = new Messenger(mHandler);
    64         }
    65     }
    66 
    67     @Override
    68     public void onDestroy(){
    69         super.onDestroy();
    70     }
    71 
    72 }

    ===================================================

    客户端代码:

      1 package com.example.messengertest_client;
      2 
      3 import androidx.appcompat.app.AppCompatActivity;
      4 import android.content.ComponentName;
      5 import android.content.Context;
      6 import android.content.Intent;
      7 import android.content.ServiceConnection;
      8 import android.os.Bundle;
      9 import android.os.Handler;
     10 import android.os.IBinder;
     11 import android.os.Message;
     12 import android.os.Messenger;
     13 import android.os.RemoteException;
     14 import android.util.Log;
     15 import android.view.View;
     16 
     17 public class MainActivity extends AppCompatActivity implements View.OnClickListener{
     18     private static final String TAG = "Client";
     19     private static final int MSG_OPCODE_1 = 1;
     20 
     21     private boolean connected;  //用一个变量记录是否连接
     22 
     23     @Override
     24     protected void onCreate(Bundle savedInstanceState) {
     25         super.onCreate(savedInstanceState);
     26         setContentView(R.layout.activity_main);
     27         findViewById(R.id.btn_connect).setOnClickListener(this);
     28         findViewById(R.id.btn_unconnect).setOnClickListener(this);
     29     }
     30 
     31     @Override
     32     protected void onDestroy(){
     33         super.onDestroy();
     34         if(connected){
     35             unbindService(mConnection);
     36         }
     37 
     38     }
     39 
     40     //处理点击操作
     41     public void onClick(View view){
     42         switch (view.getId()){
     43             case R.id.btn_connect:
     44                 Log.d(TAG,"Click btn_connect");
     45                 Intent intent = new Intent();
     46                 intent.setPackage("com.example.messengertest_server");
     47                 intent.setAction("com.example.messengertest_server.MSGSERVICE");
     48                 bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
     49                 break;
     50             case R.id.btn_unconnect:
     51                 Log.d(TAG,"Click btn_unconnect");
     52                 unbindService(mConnection);
     53                 break;
     54             default:
     55                 break;
     56         }
     57     }
     58 
     59     //ServiceConnection中的函数会被回调
     60     private ServiceConnection mConnection = new ServiceConnection() {
     61         @Override
     62         public void onServiceConnected(ComponentName name, IBinder service) {
     63             Log.d(TAG,"onServiceConnected Enter");
     64             connected = true;
     65             //建立连接后,给服务端发消息
     66             Messenger sendmessenger = new Messenger(service);
     67 
     68             Message sendmessage = Message.obtain();
     69             Bundle bundle = new Bundle();
     70             bundle.putString("client", "你好吗?");
     71             sendmessage.setData(bundle);
     72             sendmessage.what = MSG_OPCODE_1;
     73             sendmessage.replyTo = mMessenger;
     74 
     75             //利用messenger的send方法发送消息给服务端
     76             try{
     77                 sendmessenger.send(sendmessage);
     78             }catch (RemoteException e){
     79                e.printStackTrace();
     80             }
     81         }
     82 
     83         @Override
     84         public void onServiceDisconnected(ComponentName name) {
     85             Log.d(TAG,"onServiceDisconnected Enter");
     86             connected = false;
     87         }
     88     };
     89 
     90     //定义一个继承自Handler的类
     91     private static class MsgHandler extends Handler {
     92         @Override
     93         public void handleMessage(Message msg){
     94             super.handleMessage(msg);
     95             Log.d(TAG,"Handle Message Enter");
     96 
     97             //处理来自服务端回复的消息
     98             if(MSG_OPCODE_1 == msg.what)
     99             {
    100                 Bundle bundle = msg.getData();
    101                 String replymsg = bundle.getString("service");
    102                 Log.d(TAG,"Get service reply "+replymsg);
    103             }
    104         }
    105     }
    106 
    107     private MsgHandler mHandler = new MsgHandler();
    108     private Messenger mMessenger = new Messenger(mHandler);//创建一个Messenger,将Handler作为参数
    109 
    110 }
  • 相关阅读:
    【STM32H7】第3章 ThreadX GUIX和GUIX Studio介绍
    【STM32F429】第3章 ThreadX GUIX和GUIX Studio介绍
    Spring Boot Devtools 依赖详解
    《深入理解 Java 虚拟机》-- 读书笔记
    JAVA连接MySQ报错:Caused by: javax.net.ssl.SSLException: Received fatal alert: protocol_version
    JAVA生成文件的md5校验值
    IDEA启动报错:Error:java: Compilation failed: internal java compiler error
    JAVA读取本地html文件里的html文本
    SpringBoot打包实现静态文件、配置文件、jar包分离
    SpringBoot中Post请求提交富文本数据量过大参数无法获取的问题
  • 原文地址:https://www.cnblogs.com/grooovvve/p/12484284.html
Copyright © 2011-2022 走看看