1. Introduction
Messenger, as the name implies, is the messenger, through which you can pass message objects in different processes, and you can easily implement the cross-process of data by putting the incoming messages into the message that we need. Messenger is a lightweight IPC scheme whose underlying implementation is aidl.
Messenger is very simple to use, it encapsulates the aidl process, and because it processes only one request at a time, we do not need to consider synchronization issues on the server side.
2. Enabling cross-process communication
1) service-side process
First we need to create a service on the server to handle the client's connection request, create a handler and create a Messenger object from it. Then return the binder at the bottom of the Messenger object in the service's Onbind method.
2) Client Process
In the client process, you first need to bind service-side services, and after the binding succeeds, create a messenger with the IBinder object returned by the server and send a message to the server through this Messenger object. In addition, if a service-side response client is required, we need to create a handler like the server and create a new messenger, and pass the Messenger object through the ReplyTo parameter of the message. The server can respond to the client through this replyto parameter.
Messenger because it is encapsulated on the aidl, the use of the process is relatively simple, the following example enables the client to send a message to the server, the server will respond to the message sent by the client and display the results of the reply on the client.
3) The following is directly affixed to the client and service code, and finally attached the results of the operation.
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Border:none; "/>
client:package com.pignet.messengerdemo2;import android.content.componentname;import android.content.context;import android.content.intent;import android.content.serviceconnection; import android.os.handler;import android.os.ibinder;import android.os.message;import android.os.messenger;import android.os.remoteexception;import Android.support.v7.app.appcompatactivity;import android.os.bundle;import android.view.view;import android.widget.button;import android.widget.edittext;import android.widget.textview;import android.widget.toast;public class mainactivity extends appcompatactivity { private static TextView tvMsgFromService; Button btnSend; EditText etClient; private Messenger mservice; private messenger mgetReplyfromservice =new messenger (New messengerhandler ()); private static class messengerhandler extends handler{ @Override public void handlemessage (Message msg) { switch (msg.what ) { case 1: tvmsgfromservice.settext (Msg.getdata (). getString ("reply")); break; } super.haNdlemessage (msg); } } private serviceconnection mconnection = new serviceconnection () { @Override public void onserviceconnected (Componentname name, ibinder service) { mservice=new messenger (Service); } @Override public void onservicedisconnected (ComponentName name) { } }; @Override protected void oncreate (bundle savedinstancestate) { &nBsp;super.oncreate (savedinstancestate); setcontentview ( R.layout.activity_main); btnsend= (Button) Findviewbyid (r.id.btn_send); etclient= (EditText) Findviewbyid (r.id.et_client); tvmsgfromservice = ( TextView) findviewbyid (r.id.tv_msg_from_service); intent intent= new intent (Mainactivity.this,messengerservice.class); bindservice (intent,mconnection, context.bind_auto_create); btnsend.setonclicklistener (New view.onclicklistener () { @Override public void OnClick (VIEW V) { String msgFromClient; message msg = message.obtain (null,0); Bundle data = new Bundle (); if (( Msgfromclient=string.valueof (Etclient.gettext ())) ==null) { toast.maketext (MainActivity.this, "the message is null ", Toast.length_short). Show (); }else{ data.putstring ("msg", msgfromclient); msg.setdata (data); msg.replyTo= mGetReplyFromService; try { mservice.send (msg); } catch (remoteexception e) { e.printstacktrace (); } } } }); } @Override protected void ondestroy () { unbindservice (mConnection); super.ondestroy (); }}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Border:none; "/>
Service:
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Border:none; "/>
package com.pignet.messengerdemo2;import android.app.service;import android.content.intent; import android.os.bundle;import android.os.handler;import android.os.ibinder;import android.os.message;import android.os.messenger;import android.os.remoteexception;import android.support.annotation.nullable;import android.util.log;/** * created by db on 2017/7/2. */public class messengerservice extends service { private static final string tag= "Messengerservice"; private static class messengerhandler extends handler{ @Override public void Handlemessage (message msg) { switch (msg.what) { case 0: LOG.I (tag, "receive msg from client: " +msg.getdata (). getString ("msg"); messenger mservice = msg.replyto; Message replyMessage = Message.obtain (null,1); bundle bundle = new bundle (); Bundle.putstring ("Reply", "Your Information" +msg.getdata (). GETstring ("msg") + "received, will have a reply later"); replymessage.setdata (bundle); try{ mservice.send (replymessage); } catch (remoteexception e) { e.printstacktrace (); } } super.handlemessage (msg); } } private final Messenger mmessenger = new messenger (New messengerhandler ()); @Nullable @Override public ibinder onbind (intent Intent) { return mmessenger.getbinder (); }}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Border:none; "/>
In order to simulate cross-process communication between different applications, the service class is run in a different process from the client, so that it can achieve the same effect as communication between different applications.
So we need to include in the manifests file:
<android:name= ". Messengerservice " android:process=": Romote "></service >
The operation results are as follows
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/803699/201707/803699-20170702100921977-838361124. PNG "width=" 206 "height=" 379 "style=" border:0px; "/>
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/803699/201707/803699-20170702100940196-1664158337. PNG "width=" "height=" 365 "style=" border:0px; "/>
3.Messenger Source Analysis:
After entering the Messenger source, look at its structure
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/803699/201707/803699-20170702101037836-1253100020. PNG "style=" border:0px; "/>
The Messenger class has two constructors, each of which can be implemented with handler and IBinder, which is the two constructors that we have used in the instantiation Messenger class in cross-process communication.
Public Messenger (Handler target) {mtarget = Target.getimessenger (); }
Public Messenger (IBinder target) {mtarget = IMessenger.Stub.asInterface (target); }
Because the underlying implementation of Messenger is Aidl, so here I see this imessage and that Ibookmanager have similar, point open after found really so
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Border:none; "/>
public interface imessenger extends android.os.iinterface { /* * local-side ipc implementation stub class. */ public static abstract class Stub extends android.os.Binder implements android.os.IMessenger { private static final java.lang.String DESCRIPTOR = "Android.os.IMessenger"; public stub () { this.attachinterface (This, DESCRIPTOR); } public Static android.os.imessenger asinterface (...} public android.os.ibinder&Nbsp;asbinder () { return this ; } @Override public boolean ontransact (int code, android.os.parcel data, android.os.parcel reply, int flags) throws android.os.remoteexception {...} private static class proxy implements android.os.imessenger {...} public void send (android.os.message msg) throws android.os.remoteexception;}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Border:none; "/>
The method we defined for the Bookmanager class before is a Addbook and getbooklist, and here we find that Messenger adds a Send method to the Aidl package.
So where does this approach go?
Private Final class Messengerimpl extends Imessenger.stub {public void Send (Message msg) {Msg.sendingu id = binder.getcallinguid (); Handler.this.sendMessage (msg); } }
It is implemented in the Messengerimpl method in the handler class, which also explains that the message we send can appear in the handlemessage of handler.
Finally, let's go back to the Messenger class and see another important way of Messenger:
public void Send (Message message) throws RemoteException {mtarget.send (message); }
Here we can concatenate together, the Messenger class obtains the instance of IMessenger by passing in handler or IBinder, and then calls the Send method actually is the Send method that calls IMessenger remotely.
Here we are almost clearing the mechanism of Messenger.
Finally, attach a schematic diagram of the example just implemented:
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/803699/201707/803699-20170702103302243-2035895578. PNG "style=" border:0px;width:578px; "/>
Messenger of cross-process communication