日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Android进程间的通信之Messenger

發(fā)布時(shí)間:2023/12/31 综合教程 40 生活家
生活随笔 收集整理的這篇文章主要介紹了 Android进程间的通信之Messenger 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Android進(jìn)程間的通信方式可以通過以下兩種方式完成:

1 Android接口定義語言(AIDL)
2 使用Messenger綁定服務(wù)

本文我們將學(xué)習(xí)使用Messenger綁定服務(wù)的方式進(jìn)行進(jìn)程間的通信。

Android AIDL和Messenger區(qū)別

使用Messenger是執(zhí)行進(jìn)程間通信最簡單的方法,因?yàn)镸essenger會(huì)在單一線程中創(chuàng)建包含所有請(qǐng)求的隊(duì)列,這樣您就不必對(duì)服務(wù)進(jìn)行線程安全設(shè)計(jì)。而純粹的AIDL接口會(huì)同時(shí)向服務(wù)發(fā)送多個(gè)請(qǐng)求,服務(wù)隨后必須應(yīng)對(duì)多線程處理。AIDL通常應(yīng)用在服務(wù)被設(shè)計(jì)到單獨(dú)的應(yīng)用中的場(chǎng)景(即服務(wù)端可客戶端不屬于同一個(gè)app的情況),而Messenger通常應(yīng)用在同一app的不同進(jìn)程的場(chǎng)景中。

Messenger基本思想

服務(wù)端(被動(dòng)方)提供一個(gè)Service來處理客戶端(主動(dòng)方)連接,維護(hù)一個(gè)Handler(具體來講:是Handler的子類)來創(chuàng)建Messenger,在onBind時(shí)返回Messenger的binder(調(diào)用Messenger的getBinder()方法,該方法返回一個(gè)IBinder對(duì)象,客戶端將通過該對(duì)象作為參數(shù)創(chuàng)建一個(gè)Messenger對(duì)象用于與服務(wù)端進(jìn)行通信)。

Messenger使用步驟

1、服務(wù)端實(shí)現(xiàn)一個(gè)Handler,由其接收來自客戶端的每個(gè)調(diào)用的回調(diào)
2、使用第1步的Handler的實(shí)例作為target創(chuàng)建Messenger對(duì)象(即該Messenger持有了對(duì)Handler的引用)
3、使用Messenger創(chuàng)建一個(gè)IBinder(通過調(diào)用Messenger的getBinder()方法),服務(wù)端的onBind()方法中將其返回到客戶端
4、客戶端使用IBinder將Messenger(引用服務(wù)端的Handler實(shí)例)實(shí)例化,然后使用后者將Message對(duì)象發(fā)送給服務(wù)端
5、服務(wù)端在其Handler中接收每個(gè)Message

這樣,客戶端并沒有調(diào)用服務(wù)端的“方法”,而客戶端傳遞的消息(Message對(duì)象)是服務(wù)端在其Handler中接收到的。

如果想讓服務(wù)端對(duì)客戶端發(fā)回響應(yīng),則還需要在客戶端中創(chuàng)建一個(gè)持有客戶端Handler實(shí)現(xiàn)類的Messenger,當(dāng)客戶端收到onServiceConnected()回調(diào)時(shí),在向服務(wù)發(fā)送的Message時(shí),send()方法的replyTo參數(shù)中需包含客戶端的Messenger。這樣,客戶端就可在其Handler實(shí)現(xiàn)類中接收到來自服務(wù)端的響應(yīng)消息。

簡單示例

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屬性用于在一個(gè)單獨(dú)進(jìn)程中啟動(dòng)service,看如下圖片:

布局文件很簡單,這里只有一個(gè)按鈕,用于向服務(wù)端發(fā)送消息并顯示服務(wù)端響應(yīng)內(nèi)容,這里不再給出。

客戶端: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端發(fā)送消息的Messenger
 6     private Messenger mBoundServiceMessenger = null;
 7     //用于接收Service發(fā)送消息的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                     //獲取消息對(duì)象
33                     Message msg = Message.obtain(null, 1, 0, 0);
34                     try{
35                         //replyTo參數(shù)包含客戶端Messenger
36                         msg.replyTo = mReceiveMessenger;
37                         //向Service端發(fā)送消息
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      * 客戶端實(shí)現(xiàn)一個(gè)Handler用于接收服務(wù)端返回的響應(yīng)
56      * @author Administrator
57      *
58      */
59     static class ReceiveMessHandler extends Handler{
60         //持有當(dāng)前Activity的弱引用,避免內(nèi)存泄露
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 }

服務(wù)端: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                 //向客戶端響應(yīng)的消息內(nèi)容
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的實(shí)現(xiàn)類都被聲明為static并使用Service或Activity的WeakReference。如果不這樣做,編譯器會(huì)給出警告信息“This handler class should be static or leaks might occur”。通過使用弱引用的方式,就允許Service或Activity進(jìn)行垃圾收集了。

總結(jié)

以上是生活随笔為你收集整理的Android进程间的通信之Messenger的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。