Android进程间的通信之Messenger
Android進程間的通信方式可以通過以下兩種方式完成:
1 Android接口定義語言(AIDL) 2 使用Messenger綁定服務
本文我們將學習使用Messenger綁定服務的方式進行進程間的通信。
Android AIDL和Messenger區別
使用Messenger是執行進程間通信最簡單的方法,因為Messenger會在單一線程中創建包含所有請求的隊列,這樣您就不必對服務進行線程安全設計。而純粹的AIDL接口會同時向服務發送多個請求,服務隨后必須應對多線程處理。AIDL通常應用在服務被設計到單獨的應用中的場景(即服務端可客戶端不屬于同一個app的情況),而Messenger通常應用在同一app的不同進程的場景中。
Messenger基本思想
服務端(被動方)提供一個Service來處理客戶端(主動方)連接,維護一個Handler(具體來講:是Handler的子類)來創建Messenger,在onBind時返回Messenger的binder(調用Messenger的getBinder()方法,該方法返回一個IBinder對象,客戶端將通過該對象作為參數創建一個Messenger對象用于與服務端進行通信)。
Messenger使用步驟
1、服務端實現一個Handler,由其接收來自客戶端的每個調用的回調 2、使用第1步的Handler的實例作為target創建Messenger對象(即該Messenger持有了對Handler的引用) 3、使用Messenger創建一個IBinder(通過調用Messenger的getBinder()方法),服務端的onBind()方法中將其返回到客戶端 4、客戶端使用IBinder將Messenger(引用服務端的Handler實例)實例化,然后使用后者將Message對象發送給服務端 5、服務端在其Handler中接收每個Message
這樣,客戶端并沒有調用服務端的“方法”,而客戶端傳遞的消息(Message對象)是服務端在其Handler中接收到的。
如果想讓服務端對客戶端發回響應,則還需要在客戶端中創建一個持有客戶端Handler實現類的Messenger,當客戶端收到onServiceConnected()回調時,在向服務發送的Message時,send()方法的replyTo參數中需包含客戶端的Messenger。這樣,客戶端就可在其Handler實現類中接收到來自服務端的響應消息。
簡單示例
AndroidMainfest.xml
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="yf.exam.client.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MessengerService" android:process=":custom_process"/>
</application>
在上面的配置文件中,service的android:process屬性用于在一個單獨進程中啟動service,看如下圖片:
布局文件很簡單,這里只有一個按鈕,用于向服務端發送消息并顯示服務端響應內容,這里不再給出。
客戶端:MainActivity
1 public class MainActivity extends Activity {
2 private static final int REPLY_MSG_ID = 2;
3 private boolean mServiceConnected = false;
4 private Button btn = null;
5 //用于向Service端發送消息的Messenger
6 private Messenger mBoundServiceMessenger = null;
7 //用于接收Service發送消息的Messenger
8 private final Messenger mReceiveMessenger = new Messenger(new ReceiveMessHandler(this));
9 private ServiceConnection conn = new ServiceConnection() {
10 @Override
11 public void onServiceDisconnected(ComponentName name) {
12 mBoundServiceMessenger = null;
13 mServiceConnected = false;
14 }
15
16 @Override
17 public void onServiceConnected(ComponentName name, IBinder service) {
18 mBoundServiceMessenger = new Messenger(service);
19 mServiceConnected = true;
20 }
21 };
22 @Override
23 protected void onCreate(Bundle savedInstanceState) {
24 super.onCreate(savedInstanceState);
25 setContentView(R.layout.activity_main);
26 btn = (Button)findViewById(R.id.button);
27 bindService(new Intent(this, MessengerService.class), conn, Context.BIND_AUTO_CREATE);
28 btn.setOnClickListener(new View.OnClickListener() {
29 @Override
30 public void onClick(View v) {
31 if(mServiceConnected){
32 //獲取消息對象
33 Message msg = Message.obtain(null, 1, 0, 0);
34 try{
35 //replyTo參數包含客戶端Messenger
36 msg.replyTo = mReceiveMessenger;
37 //向Service端發送消息
38 mBoundServiceMessenger.send(msg);
39 }catch(RemoteException re){
40 re.printStackTrace();
41 }
42 }
43 }
44 });
45 }
46 @Override
47 protected void onDestroy() {
48 super.onDestroy();
49 if(mServiceConnected){
50 unbindService(conn);
51 mServiceConnected = false;
52 }
53 }
54 /**
55 * 客戶端實現一個Handler用于接收服務端返回的響應
56 * @author Administrator
57 *
58 */
59 static class ReceiveMessHandler extends Handler{
60 //持有當前Activity的弱引用,避免內存泄露
61 private final WeakReference<MainActivity> mActivity;
62 public ReceiveMessHandler(MainActivity activity){
63 mActivity = new WeakReference<MainActivity>(activity);
64 }
65 @Override
66 public void handleMessage(Message msg) {
67 switch(msg.what){
68 case REPLY_MSG_ID:
69 Toast.makeText(mActivity.get(), msg.getData().getString("msg"), Toast.LENGTH_SHORT).show();
70 break;
71 }
72 }
73 }
74 }
服務端:MessengerService.java
1 public class MessengerService extends Service {
2 private static final int REPLY_MSG_ID = 2;
3 private static final int MSG_ID = 1;
4 static class BoundServiceHandler extends Handler{
5 private final WeakReference<MessengerService> mService;
6 public BoundServiceHandler(MessengerService service){
7 mService = new WeakReference<MessengerService>(service);
8 }
9 @Override
10 public void handleMessage(Message msg) {
11 switch(msg.what){
12 case MSG_ID:
13 Messenger replyMessenger = msg.replyTo;
14 Message replyMsg = Message.obtain(null, REPLY_MSG_ID);
15 //向客戶端響應的消息內容
16 Bundle b = new Bundle();
17 b.putString("msg", "this is the message reply from service");
18 replyMsg.setData(b);
19 try{
20 replyMessenger.send(replyMsg);
21 }catch(RemoteException re){
22 re.printStackTrace();
23 }
24 break;
25 default:
26 super.handleMessage(msg);
27 }
28 }
29 }
30 private final Messenger mMessenger = new Messenger(new BoundServiceHandler(this));
31 @Override
32 public IBinder onBind(Intent intent) {
33 Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
34 return mMessenger.getBinder();
35 }
36 }
此外,上述例子中所有的Handler的實現類都被聲明為static并使用Service或Activity的WeakReference。如果不這樣做,編譯器會給出警告信息“This handler class should be static or leaks might occur”。通過使用弱引用的方式,就允許Service或Activity進行垃圾收集了。
總結
以上是生活随笔為你收集整理的Android进程间的通信之Messenger的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 精美的反义词
- 下一篇: matlab神经网络每次相差大,GA-B