Bound服務之Messenger

在上一篇介紹了Bound服務之Binder.這一篇繼續介紹Bound服務之Messenger.

適用場景:如果你的服務需要與遠程進程進行通信,那你可以使用一個 Messenger 來提供服務的接口。這種技術能讓你無需使用AIDL就能進行進程間通信(IPC)。

Messenger使用方法:

1.服務實現一個Handler ,用於客戶端每次調用時接收回調。

2.此Handler用於創建一個Messenger對象(它是一個對Handler的引用)。
3.此Messenger對象創建一個IBinder,服務在onBind()中把它返回給客戶端。

4.客戶端用IBinder將Messenger(引用服務的Handler)實例化,客戶端用它向服務發送消息對象Message。

5.服務接收Handler中的每個消息Message——確切的說,是在handleMessage()方法中接收。

這種實現的的原理是:客戶端發送消息(Messenger),服務則接收位於 Handler中的這個消息。

Service服務端代碼:

public class MessengerService extends Service {
    /* 發送給服務的用於顯示信息的指令*/
    static final int MSG_SAY_HELLO = 1;

    /* 1.服務實現一個Handler ,用於客戶端每次調用時接收回調。*/
    class IncomingHandler extends Handler {
        @Override
    /* 5.服務接收Handler中的每個消息Message——確切的說,是在handleMessage()方法中接收。*/
        public void handleMessage(Message msg) {
               /*根據不同的Message信息執行相應的邏輯函數*/
            }
        }
    }

    /**
        2.此Handler用於創建一個Messenger對象(它是一個對Handler的引用)。
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * 當綁定到服務時,我們向Messager返回接口,
     * 用於向服務發送消息
     */
    @Override
    public IBinder onBind(Intent intent) {
    /*3.此Messenger對象創建一個IBinder,服務在onBind()中把它返回給客戶端。*/
        return mMessenger.getBinder();
    }
}

客戶端代碼:

客戶端要做的全部工作就是根據服務返回的IBinder創建一個 Messenger ,並用send() 方法發送一個消息。

public class ActivityMessenger extends Activity {
    /** 用於和服務通信的Messenger*/
    Messenger mService = null;


   /** 標識我們是否已綁定服務的標誌 */
    boolean mBound;

    /**
     * 與服務的主接口進行交互的類
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // 與服務建立聯接後將會調用本方法,
            // 給出用於和服務交互的對象。
            // 我們將用一個Messenger來與服務進行通信,
            // 因此這裏我們獲取到一個原始IBinder對象的客戶端實例。

           /*4.客戶端用IBinder將Messenger(引用服務的Handler)實例化,客戶端用它向服務發送消息對象Message。*/
            mService = new Messenger(service);
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            // 當與服務的聯接被意外中斷時——也就是說服務的進程崩潰了,
            // 將會調用本方法。
            mService = null;
            mBound = false;
        }
    };

    public void sayHello(View v) {
        if (!mBound) return;
        // 創建並向服務發送一個消息,用到了已約定的'what'值
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // 綁定服務
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    //解除綁定
    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

注意這段代碼中的幾個函數:

//獲取Messenger 對象,構造函數的參數爲Handler或其子類
Messenger ms=new Messenger(Handler);
//通過Messenger對象獲取一個 IBinder對象
IBinder ib=ms.getBinder();
//獲取Messenger 對象,構造函數爲 IBinder對象
Messenger mService=new Messenger(IBinder);

Bound的生命週期

發佈了27 篇原創文章 · 獲贊 11 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章