Android Process Communication Using Messenger and androidmessenger
Messenger can be used for inter-process communication, while Messenger queues Service requests, so it does not support multi-thread communication.
Take a look at the official documentation's explanation of Messenger:
Reference to a Handler, which others can use to send messages to it. This allows for the implementation
Message-based communication processing SS processes, by creating a Messenger pointing to a Handler in one process,
And handing that Messenger to another process.
The client and server can communicate with each other by holding the other's Messenger. Let's take a look at the specific implementation.
Create two projects under eclipse: client and server:
The implementation of the client creates the client's Messenger and points to a handler instance using the Messenger constructor. This handler is used to process messages sent from the server.
The client obtains the Messenger of the server through onServiceConnected, and uses this Messenger to send messages to the server. The Messenger of the client passes the Message replyTo to the server.
1 public class MainActivity extends Activity {2 3 private static final String TAG = "-- DEBUG --"; 4 5 // 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 @ Override14 pr Otected 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 @ Override20 public void onClick (View v) {21 bindService (new Intent (START_SERVER_ACTION), conn, Context. BIND_AUTO_CREATE); 22} 23}); 24} 25 26 // client Handler To process the Message 27 from the server. private Handler mClientHandler = new Handler (new Callback () {28 @ Override29 public boolean handleMessage (Message msg) {30 switch (msg. what) {31 case WHAT_ON_TO_CLIENT: 32 Log. v (TAG, "the client receives a message from the server! "); 33 break; 34 35 default: 36 break; 37} 38 return false; 39} 40 }); 41 42 // client Messenger43 private Messenger mClientMessenger = new Messenger (mClientHandler); 44 45 private ServiceConnection conn = new ServiceConnection () {46 47 @ Override48 public void onServiceDisconnected (ComponentName) {49 Log. v (TAG, "service disconnected"); 50 51 isBindService = false; 52 mClientMessenger = null; 53} 54 55 @ Override56 public void onServiceConnected (ComponentName, IBinder service) {57 Log. v (TAG, "service linked"); 58 59 isBindService = true; 60 // get the server-side message to make the Messenger instance 61 Messenger serverMessenger = new Messenger (service ); 62 // The Message 63 Message toServerMessage = Message sent to the server. obtain (null, WHAT_ON_TO_SERVICE); 64 // transmits the client messenger to service65 toServerMessage through replyTo. 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}
After the server receives a Message from the client, the server extracts the Messenger from the client through Message replyTo and sends the Message to the client. This enables two-way communication between processes.
The server returns the IBinder object to the client through the getBinder method of Messenger, which is used to share the Messenger of the server.
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-side handler, used to process messages sent from client 8 private Handler mServerHandler = new Handler (new Callback () {9 @ Override10 public boolean handleMessage (Message msg) {11 switch (msg. what) {12 case WHAT_ON_TO_SERVICE: 13 Log. v (TAG, "received messages from the client"); 14 // The server obtains the client's Messenger Messenger15 Messenger clientMessenger = msg. replyTo; 16 Message toClientMsg = Message. obtain (null, WHAT_ON_TO_CLIENT); 17 try {18 // use client Messenger to send messages to client 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 // enable Messenger33 private Messenger mServerMessenger = new Messenger (mServerHandler); 34 35 @ Override36 public IBinder onBind (Intent intent) {37 return mServerMessenger. getBinder (); 38}
Let's take a look at the service declaration on the server. to start the service in other processes, set android: exported to true. In addition, add the start permission to the 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>
At last, you must add the corresponding Service start permissions on the client.
<uses-permission android:name="young.permission.START_SERVICE" />
After the program runs, you can see that both the client and the server have received messages from the other party.
11-12 12:58:37. 197: V/-- DEBUG -- (21322): the service is linked.
11-12 12:58:37. 197: V/-- DEBUG -- (21268): receives a message from the client.
11-12 12:58:37. 197: V/-- DEBUG -- (21322): the client receives a message from the server!