Android Service完全解析(二)

Service完全解析(二)

1.Messenger介紹
2.使用Messenger實現跨進程通信
3.相關知識點及注意事項


Messenger扮演信使的角色,它指向一個Handler,可以通過這個信使向其指向的Handler傳遞數據。

要實現跨進程通信,其實質是在不同進程間傳遞Messenger。客戶端向服務器端發送數據,只要得到服務器端的信使,然後調用send()方法即可;服務器端向客戶端發送數據也一樣,先得到客戶端的信使,調用send()方法即可。

服務器端向客戶端傳遞信使的方法是:
(1)創建Messenger對象;
(2)在onBind()方法中返回Messenger.getBind();
(3)客戶端在onServiceConnected()方法中以new Messenger(IBinder對象)的方法獲取到一個Messenger,這個Messenger就是服務器端的信使。
客戶端向服務器端傳遞信使的方法是:
(1)創建一個Messenger對象;
(2)創建一個Message對象,這個對象是要發送給服務器的;
(3)將上面創建的Messenger對象給Message對象:Message.replyTo = Messenger;
(4)將這個Message對象發送給服務器端即可。

代碼分析:

服務器端代碼:

    public MessageService() {

        /*創建一個Handler處理來自客戶端的Message*/
        mHandler = new Handler(){
            @Override
            public void handleMessage(Message msgfromclient){
                Log.v("out","當前線程:"+android.os.Process.myPid()+"收到客戶端的數據爲:"+msgfromclient.what);
                /*得到來自客戶端的信使*/
                Messenger messengerfromclient = msgfromclient.replyTo;
                Message messagetoclient = Message.obtain(null,123456789);
                try {
                    messengerfromclient.send(messagetoclient);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        };
        /*根據上面的Handler生成一個Messenger對象,Messenger:信使,指向一個Handler,可以通過
        * 這個Messenger來將Message發給其指向的Handler處理*/
        mMessenger = new Messenger(mHandler);

    }

    @Override
    public IBinder onBind(Intent intent) {
        /*通過這一步操作將Messenger返給客戶端*/
        return mMessenger.getBinder();
    }

客戶端代碼:

private ServiceConnection conn;
    private Messenger mMessengerService,mMessengerClient;
    private Message msgToService;

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

        mMessengerClient = new Messenger(new Handler(){
            @Override
            public void handleMessage(Message msgfromservice){
                Log.v("out","收到了來自服務器端的數據:"+msgfromservice.what);
            }
        });

        /*爲了能讓服務器也給客戶端發送數據,我們需要將客戶端的信使傳遞給服務器端,服務器端將信使傳遞給
        * 客戶端的方式是通過Binder,客戶端將信使傳遞給服務器端的方式是將信使封裝到Message對象中*/
        msgToService = Message.obtain(null,123321);
        msgToService.replyTo = mMessengerClient;

        /*首先創建ServiceConnection,並從中獲取到服務器端的Messenger*/
        conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                /*得到的是服務端的信使,我們通過這個信使將數據發給服務端*/
                mMessengerService = new Messenger(service);
                try {
                    mMessengerService.send(msgToService);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
        bindService(new Intent(MessageServiceActivity.this, MessageService.class),conn,this.BIND_AUTO_CREATE);

    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        unbindService(conn);
    }

其他相關知識點
(1)Service運行在UI線程中的。
(1)unBindService()後Service會調用onDestroy()方法,如果Service新開了線程,此時線程仍會執行,如果想關閉,可以在onDestroy()中設置標誌。同時,由於onServiceConnected()方法中有Service的Binder的引用,此時仍然可以調用Service中的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章