Messenger,信使,可以使用它進行進程間的通訊,而Messenger對Service的請求採用隊列的方式,所以它不支持多線程通訊。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): 客戶端收到服務端發來的消息!