Android進程間通訊之使用Messenger

Messenger,信使,可以使用它進行進程間的通訊,而MessengerService的請求採用隊列的方式,所以它不支持多線程通訊。android

 

看看官方文檔對於Messenger的解釋:多線程

 

Reference to a Handler, which others can use to send messages to it. This allows for the implementation ofeclipse

message-based communication across processes, by creating a Messenger pointing to a Handler in one process,ide

and handing that Messenger to another process.spa

客戶端和服務端可相互持有對方的Messenger來進行通訊,下面咱們來看看具體的實現。線程

在eclipse下建立兩個工程,分別爲客戶端和服務端:code

客戶端的實現,建立客戶端的Messenger,使用Messenger的構造方法指向一個handler實例,此handler用於處理服務端發過來的消息。orm

而客戶端經過onServiceConnected得到服務端的Messenger,使用此Messenger給服務端發送消息,客戶端的Messenger經過Message的replyTo傳遞給服務端。server

 1 public class MainActivity extends Activity {
 2 
 3     private static final String TAG = "--DEBUG--";
 4 
 5     // 用於啓動service的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     @Override
14     protected 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             @Override
20             public void onClick(View v) {
21                 bindService(new Intent(START_SERVER_ACTION), conn, Context.BIND_AUTO_CREATE);
22             }
23         });
24     }
25 
26     // client端Handler,用於處理server端發來的消息
27     private Handler mClientHandler = new Handler(new Callback() {
28         @Override
29         public boolean handleMessage(Message msg) {
30             switch (msg.what) {
31             case WHAT_ON_TO_CLIENT:
32                 Log.v(TAG, "客戶端收到服務端發來的消息!");
33                 break;
34 
35             default:
36                 break;
37             }
38             return false;
39         }
40     });
41 
42     // client端Messenger
43     private Messenger mClientMessenger = new Messenger(mClientHandler);
44 
45     private ServiceConnection conn = new ServiceConnection() {
46 
47         @Override
48         public void onServiceDisconnected(ComponentName name) {
49             Log.v(TAG, "服務已斷開");
50 
51             isBindService = false;
52             mClientMessenger = null;
53         }
54 
55         @Override
56         public void onServiceConnected(ComponentName name, IBinder service) {
57             Log.v(TAG, "服務已連接");
58 
59             isBindService = true;
60             // 得到server端信使Messenger實例
61             Messenger serverMessenger = new Messenger(service);
62             // 向server端發送的消息
63             Message toServerMessage = Message.obtain(null, WHAT_ON_TO_SERVICE);
64             // 經過replyTo把client端的信使傳遞給service
65             toServerMessage.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 }

 

服務端Service的實現,服務端接收到客戶端的消息之後,經過Message的replyTo取出客戶端的Messenger,使用此Messenger給客戶端發送消息,這就實現了進程之間的雙向通訊。對象

服務端經過Messenger的getBinder方法將IBinder對象返給客戶端,用於共享服務端的Messenger。

 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端handler,用來處理client發來的消息
 8     private Handler mServerHandler = new Handler(new Callback() {
 9         @Override
10         public boolean handleMessage(Message msg) {
11             switch (msg.what) {
12             case WHAT_ON_TO_SERVICE:
13                 Log.v(TAG, "收到客戶端發來的消息");
14                 // server端得到client端的信使Messenger
15                 Messenger clientMessenger = msg.replyTo;
16                 Message toClientMsg = Message.obtain(null, WHAT_ON_TO_CLIENT);
17                 try {
18                     // 使用客戶端Messenger向客戶端發送消息
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     // server端信使Messenger
33     private Messenger mServerMessenger = new Messenger(mServerHandler);
34 
35     @Override
36     public IBinder onBind(Intent intent) {
37         return mServerMessenger.getBinder();
38     }

再來看看服務端service的聲明,由於要在其餘進程中啓動service,因此設置android:exported爲true,此外還爲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>

最後要在客戶端添加相應的啓動Service權限。

<uses-permission android:name="young.permission.START_SERVICE" />

 

程序運行後的結果,能夠看到客戶端和服務端都收到了對方發來的消息。

11-12 12:58:37.197: V/--DEBUG--(21322): 服務已連接
11-12 12:58:37.197: V/--DEBUG--(21268): 收到客戶端發來的消息11-12 12:58:37.197: V/--DEBUG--(21322): 客戶端收到服務端發來的消息!

相關文章
相關標籤/搜索