Service官方教程(8)Bound Service示例之2-跨进程使用Messenger

Using a Messenger

  If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.

  Here's a summary of how to use a Messenger:

 使用Messenger的步骤:

  In this way, there are no "methods" for the client to call on the service. Instead, the client delivers "messages" (Message objects) that the service receives in its Handler.

 注意,这种方式下,服务端没有函数给客户端调用。它们只能发送消息。

  Here's a simple example service that uses a Messenger interface:

 1 public class MessengerService extends Service {
 2     /** Command to the service to display a message */
 3     static final int MSG_SAY_HELLO = 1;
 4 
 5     /**
 6      * Handler of incoming messages from clients.
 7      */
 8     class IncomingHandler extends Handler {
 9         @Override
10         public void handleMessage(Message msg) {
11             switch (msg.what) {
12                 case MSG_SAY_HELLO:
13                     Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
14                     break;
15                 default:
16                     super.handleMessage(msg);
17             }
18         }
19     }
20 
21     /**
22      * Target we publish for clients to send messages to IncomingHandler.
23      */
24     final Messenger mMessenger = new Messenger(new IncomingHandler());
25 
26     /**
27      * When binding to the service, we return an interface to our messenger
28      * for sending messages to the service.
29      */
30     @Override
31     public IBinder onBind(Intent intent) {
32         Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
33         return mMessenger.getBinder();
34     }
35 }

  Notice that the handleMessage() method in the Handler is where the service receives the incoming Message and decides what to do, based on the what member.

  All that a client needs to do is create a Messenger based on the IBinder returned by the service and send a message using send(). For example, here's a simple activity that binds to the service and delivers the MSG_SAY_HELLO message to the service:

 1 public class MessengerActivity extends Activity {
 2     /** Messenger for communicating with the service. */
 3     Messenger mService = null;
 4 
 5     /** Flag indicating whether we have called bind on the service. */
 6     boolean mBound;
 7 
 8     /**
 9      * Class for interacting with the main interface of the service.
10      */
11     private ServiceConnection mConnection = new ServiceConnection() {
12         public void onServiceConnected(ComponentName className, IBinder service) {
13             // This is called when the connection with the service has been
14             // established, giving us the object we can use to
15             // interact with the service.  We are communicating with the
16             // service using a Messenger, so here we get a client-side
17             // representation of that from the raw IBinder object.
18             mService = new Messenger(service);
19             mBound = true;
20         }
21 
22         public void onServiceDisconnected(ComponentName className) {
23             // This is called when the connection with the service has been
24             // unexpectedly disconnected -- that is, its process crashed.
25             mService = null;
26             mBound = false;
27         }
28     };
29 
30     public void sayHello(View v) {
31         if (!mBound) return;
32         // Create and send a message to the service, using a supported 'what' value
33         Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
34         try {
35             mService.send(msg);
36         } catch (RemoteException e) {
37             e.printStackTrace();
38         }
39     }
40 
41     @Override
42     protected void onCreate(Bundle savedInstanceState) {
43         super.onCreate(savedInstanceState);
44         setContentView(R.layout.activity_messenger);
45     }
46 
47     @Override
48     protected void onStart() {
49         super.onStart();
50         // Bind to the service
51         bindService(new Intent(this, MessengerService.class), mConnection,
52                 Context.BIND_AUTO_CREATE);
53     }
54 
55     @Override
56     protected void onStop() {
57         super.onStop();
58         // Unbind from the service
59         if (mBound) {
60             unbindService(mConnection);
61             mBound = false;
62         }
63     }
64 }

  Notice that this example does not show how the service can respond to the client. If you want the service to respond, then you need to also create a Messenger in the client. Then when the client receives the onServiceConnected() callback, it sends a Message to the service that includes the client's Messenger in the replyTo parameter of the send() method.

  You can see an example of how to provide two-way messaging in the MessengerService.java (service) and MessengerServiceActivities.java (client) samples.

 

posted @ 2016-09-23 16:49  f9q  阅读(241)  评论(0编辑  收藏  举报