Android IPC 通信机制之一 Messenger 模式

在介绍使用Messenger跨进程通信之前先要了解以下问题:多进程是啥?我个人将不同进程简单的理解为不同的应用程序,当然也有例外,比如可以在同一个应用程序中开启两个或多个进程。由于进程之间不能像线程一样共享内存,所以数据通信不能像线程一般进行。在Android中可以使用广播,Messenger,AIDL和Socket进行跨进程通信。本章利用Messenger进行多进程双向通信。

Messenger是通过使用Message来实现跨进程通信,一次实现一个请求的方式,这是它的优点也是缺点。

其底层实现为AIDL(下篇讲解icp通信机制之二),Messenger的优点是:

1.基于Message,方便使用;

2.支持回调的方式,也就是服务端处理完成长任务可以和客户端交互;

3.不需要编写aidl文件。

Messenger使用流程如下:

Service实现:

(记得在mainfest中注册<serviceandroid:name="com.lzy.cn.ble.BleService"android:process=":remote"/>這樣service就是另一個進程了 

具体思路是:

创建一个Handler对象用来处理客户端发送来的消息,再创建一个Messenger对象将上面的Handler对象作为参数传入,这样我们就获得了一个信使。下面就是通过getBinder()把这个信使创建的Binder对象返回给客户端(一旦客户端拿到这个Binder,又可以将它还原为Messenger)。Handler中处理信息为:当得到的Message的what值为MSG_REGISTER時候,用客戶端Messenger引用回復。

public class BleService extends Service {
   static final int MSG_REGISTER = 1;
   static final int MSG_UNREGISTER = 2;
   static final int MSG_TO_CLIENT = 3;

   private final IncomingHandler mHandler = new IncomingHandler(this);
   private final Messenger mMessenger = new Messenger(mHandler);


   private final List<Messenger> mClients = new LinkedList<Messenger>();//维护客户端Messenger的队列
   private Messenger clientMessenger = null;

   @Override
   public IBinder onBind(Intent intent) {
      return mMessenger.getBinder();
   }

   private static class IncomingHandler extends Handler {
      private final WeakReference<BleService> mService;

      public IncomingHandler(BleService service) {
         //弱引用可以使我们保持对父类对象的引用,并且不会阻止它被垃圾回收机制回收(静态内部类不持有访问父类属性和方法的能力)
         mService = new WeakReference<BleService>(service);
      }

      @Override
      public void handleMessage(Message msg) {
         BleService service = mService.get();
         if (service != null) {
            switch (msg.what) {
               case MSG_REGISTER://收到客户端注册消息
                  service.mClients.add(msg.replyTo);//msg.replyTo 为客户端传过来的Messenger对象
                  service.clientMessenger = msg.replyTo;
                  Message msg1 = Message.obtain();
                  msg1.what = MSG_TO_CLIENT;
                  Bundle bundle = new Bundle();
                  bundle.putString("msg", "欢迎客户端注册");
                  msg1.setData(bundle);
                  try {
                     service.clientMessenger.send(msg1);
                  } catch (RemoteException e) {
                     e.printStackTrace();
                  }
                  break;
               case MSG_UNREGISTER://收到客户端取消注册消息
                  service.mClients.remove(msg.replyTo);
                  Log.d(TAG, "Unegistered");
                  break;
               default:
                  super.handleMessage(msg);
            }
         }
      }
   }
}


Activity实现

 在客户端中我们应该做的是:通过bindservice拿到服务端传来的Messenger对象,然后创建一个Message对象,为Message写入数据,注意Message中的what要与服务端中Handler对象中的what一致。使用该Messenger通过send()将Message发送给服务端,这样就可以实现客户端与服务端的双向通信了

public class BleActivity extends Activity  {


   private final Messenger mMessenger = new Messenger(new IncomingHandler(this));

   private Intent mServiceIntent;
   private Messenger mService = null;

   private ServiceConnection mConnection = new ServiceConnection() {
      @Override
      public void onServiceConnected(ComponentName name, IBinder service) {
         mService = new Messenger(service);//通过IBinder获取服务端的messenger引用
         try {
            Message msg = Message.obtain(null, BleService.MSG_REGISTER);
            if (msg != null) {
               msg.replyTo = mMessenger;
               mService.send(msg);//将自己的Messenger发给服务端引用
            } else {
               mService = null;
            }
         } catch (Exception e) {
            Log.w(TAG, "Error connecting to BleService", e);
            mService = null;
         }
      }

      @Override
      public void onServiceDisconnected(ComponentName name) {
         mService = null;
      }
   };


   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_ble);
      mServiceIntent = new Intent(this, BleService.class);
   }
   @Override
   protected void onStart() {
      super.onStart();
      bindService(mServiceIntent, mConnection, BIND_AUTO_CREATE);
   }
   @Override  
   protected void onStop() {      
      if (mService != null) {         
         try {            
            Message msg = Message.obtain(null, BleService.MSG_UNREGISTER);            
            if (msg != null) {              
               msg.replyTo = mMessenger;             
               mService.send(msg);           
            }       
         } catch (Exception e) {       
            Log.w(TAG, "Error unregistering with BleService", e);      
            mService = null;     
         } finally {            
            unbindService(mConnection);    
         }    
      }      
      super.onStop();  
   }
   private static class IncomingHandler extends Handler {
      private final WeakReference<BleActivity> mActivity;

      public IncomingHandler(BleActivity activity) {
         mActivity = new WeakReference<BleActivity>(activity);
      }

      @Override
      public void handleMessage(Message msg) {
         BleActivity activity = mActivity.get();
         if (activity != null) {
            switch (msg.what) {
               case BleService.MSG_TO_CLIENT :
                  Bundle bundle = msg.getData()
                  String textMsg = bundle.getString("msg")
                  Log.i("tag","客户端回復你:"+textMsg );
                  break;
            }
         }
         super.handleMessage(msg);
      }
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值