Android 进程间通信 Messenger

Android进程间通信 Messenger 允许实现基于消息的进程间通信的方式

可以看到,我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。此外,还支持,记录客户端对象的Messenger,然后可以实现一对多的通信

Messenger使用步骤

以下是如何使用Messenger的步骤:
1. Service需要实现一个Hanlder,用以处理从客户端收到的消息
2. 用该Handler创建一个Messenger对象,Messenger对象内部会引用该Handler对象
3. 用创建好的Messenger对象获得一个IBinder实例,并且将该IBinder通过Service的onBind方法返回给各个客户端
4. 客户端通过收到的IBinder对象实例化一个Messenger对象,该Messenger内部指向指向Service中的Handler。客户端通过该Messenger对象就可以向Service中的Hanlder发送消息。
5. Service中的Hanlder收到消息后,在Handler中的handleMessage方法中处理消息。
6. 通过上面的第4步与第5步,就完成了客户端向Service发送消息并且Service接收到消息的单向通信过程,即客户端 -> Service。如果要实现Service向客户端回消息的通信过程,即Service -> 客户端,那么前提是在客户端中也需要像Service一样内部维护有一个指向Handler的Messenger。当在第四步中客户端向Service发送信息时,将Message的replyTo属性设置为客户端自己的Messenger。这样在第5步Service在Handler的handleMessage中处理收到的消息时,可以通过Message的Messenger再向客户端发送Message,这样客户端内维护的Handler对象就会收到来自于Service的Message,从而完成Service向客户端发送消息且客户端接收到消息的通信过程。

综上六步就能完成客户端与Service的跨进程双向通信过程:
客户端 -> Service -> 客户端

Messenger Server端

package com.fate.messengerserver;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class MessengerService extends Service {

    private static final int MSG_SUM = 0x110;
    //clientMessenger表示的是客户端的Messenger,可以通过来自于客户端的Message的replyTo属性获得,
    //其内部指向了客户端的ClientHandler实例,可以用clientMessenger向客户端发送消息
    private Messenger clientMessenger = null;

    //serviceMessenger是Service自身的Messenger,其内部指向了ServiceHandler的实例
    //客户端可以通过IBinder构建Service端的Messenger,从而向Service发送消息,
    //并由ServiceHandler接收并处理来自于客户端的消息
    private Messenger serviceMessenger = new Messenger(new ServiceHandler());


    //MyService用ServiceHandler接收并处理来自于客户端的消息
    private class ServiceHandler extends Handler {
        @Override
        public void handleMessage(Message msgfromClient) {
            Message msgToClient = Message.obtain(msgfromClient);//返回给客户端的消息
            switch (msgfromClient.what)
            {
                //msg 客户端传来的消息
                case MSG_SUM:
                    msgToClient.what = MSG_SUM;
                    try
                    {
                        //模拟耗时
                        Thread.sleep(1000);
                        msgToClient.arg2 = msgfromClient.arg1 + msgfromClient.arg2;
                        //通过Message的replyTo获取到客户端自身的Messenger,
                        //Service可以通过它向客户端发送消息
                        clientMessenger = msgfromClient.replyTo;
                        clientMessenger.send(msgToClient);
                        Log.i("fate","Messenger Server -> result "+msgToClient.arg2);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    } catch (RemoteException e)
                    {
                        e.printStackTrace();
                    }
                    break;
            }

            super.handleMessage(msgfromClient);
        }
    }

    @Override
    public void onCreate() {
        Log.i("fate", "Messenger Server -> onCreate");
        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i("fate", "Messenger Server -> onBind");
        //获取Service自身Messenger所对应的IBinder,并将其发送共享给所有客户端
        return serviceMessenger.getBinder();
    }

    @Override
    public void onDestroy() {
        Log.i("fate", "Messenger Server -> onDestroy");
        clientMessenger = null;
        super.onDestroy();
    }
}
服务端就一个Service,可以看到代码相当的简单,只需要去声明一个Messenger对象,然后onBind方法返回mMessenger.getBinder();
然后坐等客户端将消息发送到handleMessage想法,根据message.what去判断进行什么操作,然后做对应的操作,最终将结果通过 msgfromClient.replyTo.send(msgToClient);返回。

Service注册

<service
    android:name=".MessengerService"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.fate.messenger.client"></action>
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

Messenger Client端

package com.fate.messengerclient;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private static final String TAG = "fate";
    private static final int MSG_SUM = 0x110;

    private Button mBtnAdd, mBindBtn, mUnBindBtn;
    private LinearLayout mLyContainer;
    //显示连接状态
    private TextView mTvState;
    private Messenger mService;
    private boolean isConn;


    private Messenger mMessenger = new Messenger(new Handler(){
        @Override
        public void handleMessage(Message msgFromServer) {
            switch (msgFromServer.what) {
                case MSG_SUM:
                    TextView tv = (TextView) mLyContainer.findViewById(msgFromServer.arg1);
                    tv.setText(tv.getText() + "=>" + msgFromServer.arg2);
                    break;
            }
            super.handleMessage(msgFromServer);
        }
    });


    private ServiceConnection mConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i("fate","Messenger Client -> onServiceConnected");
            mService = new Messenger(service);
            isConn = true;
            mTvState.setText("connected!");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i("fate","Messenger Client -> onServiceDisconnected");
            mService = null;
            isConn = false;
            mTvState.setText("disconnected!");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvState = (TextView) findViewById(R.id.id_tv_callback);
        mBtnAdd = (Button) findViewById(R.id.id_btn_add);
        mLyContainer = (LinearLayout) findViewById(R.id.id_ll_container);
        mBtnAdd.setOnClickListener(this);
        //开始绑定服务
        bindServiceInvoked();
    }

    private void bindServiceInvoked() {
        Intent intent = new Intent();
        intent.setAction("com.fate.messenger.client");
        intent.setPackage("com.fate.messengerserver");
        bindService(intent, mConn, Context.BIND_AUTO_CREATE);
        Log.i("fate", "Messenger Client -> bindService invoked !");
    }

    @Override
    protected void onDestroy() {
        Log.i("fate", "Messenger Client -> onDestroy ");
        super.onDestroy();
        unbindService(mConn);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){
            case R.id.id_btn_add:
                try {
                    int a = (int) (Math.random() * 100);
                    int b = (int) (Math.random() * 100);

                    //创建一个tv,添加到LinearLayout中
                    TextView tv = new TextView(MainActivity.this);
                    tv.setText(a + " + " + b + " = caculating ...");
                    tv.setId(a);
                    mLyContainer.addView(tv);

                    Message msgFromClient = Message.obtain(null, MSG_SUM, a, b);
                    msgFromClient.replyTo = mMessenger;
                    if (isConn) {
                        //往服务端发送消息
                        mService.send(msgFromClient);
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
        }
    }
}

首先bindService,然后在onServiceConnected中拿到回调的service(IBinder)对象,通过service对象去构造一个mService =new Messenger(service);然后就可以使用mService.send(msg)给服务端了。
那么服务端会收到消息,处理完成会将结果返回,传到Client端的mMessenger中的Handler的handleMessage方法中。

fate    : Messenger Client -> bindService invoked !
fate    : Messenger Server -> onCreate
fate    : Messenger Server -> onBind
fate    : Messenger Client -> onServiceConnected
fate    : Messenger Server -> result 65
fate    : Messenger Client -> onDestroy 
fate    : Messenger Server -> onDestroy

相关文章

http://blog.csdn.net/lmj623565791/article/details/47017485
http://blog.csdn.net/iispring/article/details/48329925

http://blog.csdn.net/qq379454816/article/details/52573476

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值