android—进程间通信之Messenger

Messenger类

Messenger类利用Binder实现进程间通信,

public final class Messenger implements Parcelable {
    private final IMessenger mTarget;
    /*
    server端Messenger构造函数,输入为一个Handler,用来处理消息
    */
    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
    /**
     * Retrieve the IBinder that this Messenger is using to communicate with
     * its associated Handler.
     * 
     * @return Returns the IBinder backing this Messenger.
    */
    //server端在onBind时调用,返回IMessenger 
    public IBinder getBinder() {
        return mTarget.asBinder();
    }

     /**
     * Create a Messenger from a raw IBinder, which had previously been
     * retrieved with {@link #getBinder}.
     * 
     * @param target The IBinder this Messenger should communicate with.
     */
     //构造MessengerImpl的client端IBinder
    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }

        /**
     * Send a Message to this Messenger's Handler.
     * 
     * @param message The Message to send.  Usually retrieved through
     * {@link Message#obtain() Message.obtain()}.
     * 
     * @throws RemoteException Throws DeadObjectException if the target
     * Handler no longer exists.
     */
     //send函数也是借助mTarget,即IMessenger发送数据
    public void send(Message message) throws RemoteException {
        mTarget.send(message);
    }   
}

关于target.getIMessenger(),即Handler的getIMessenger(),

    final IMessenger getIMessenger() {
        synchronized (mQueue) {
            if (mMessenger != null) {
                return mMessenger;
            }
            //MessengerImpl是IMessenger server端的对象
            mMessenger = new MessengerImpl();
            return mMessenger;
        }
    }

    //MessengerImpl是server,实现了IMessenger.aidl的接口
    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            msg.sendingUid = Binder.getCallingUid();
            //server端将该meg交给handler处理
            Handler.this.sendMessage(msg);
        }
    }

1. Messenger实现IPC的关键其实是借助了IMessenger mTarget,client通过send()发送message,到server端调用的是MessengerImpl的send(),将msg交给Handler处理;
2. 一个Messenger和一个handler相关联,Messenger只是信使,把信送到handler,处理还是由handler处理。

简单例子

server端,

public class MessengerService extends Service {
    /** Command to the service to display a message */
    static final int MSG_SAY_HELLO = 1;

    /**
     * Handler of incoming messages from clients.
     * server端处理消息的handler
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     * server端构造一个Messenger,和自定义的Handler相关联
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     * client可以调用bindService()绑定到一个service.
     * Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder.
     * 这里返回的是MessengerImpl对象
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}

client端,

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;

    /** Flag indicating whether we have called bind on the service. */
    boolean mBound;

    /**
     * Class for interacting with the main interface of the service.
     * client通过bindService()去连接service,
     * 绑定是异步的.bindService()会立即返回,它不会返回IBinder给客户端.要接收IBinder,
     * 客户端必须创建一个ServiceConnection的实例并传给bindService().ServiceConnection
     * 包含一个回调方法,系统调用这个方法来传递要返回的IBinder.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            // 利用IMessenger创建Messenger
            mService = new Messenger(service);
            mBound = true;
            //给server端发送数据
            sayHello();
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound = false;
        }
    };

    public void sayHello() {
        if (!mBound) return;
        // Create and send a message to the service, using a supported 'what' value
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            //调用send函数发送数据
            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();
        // Bind to the service
        // client调用bindService()
        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;
        }
    }
}

上面的例子演示了client向server端发送数据,server接收,但是有时候server也想回应client,其实做法是类似的,如果想要server响应client,我们需要在client中创建一个handler并创建一个新的Messenger(server),并把这个Messenger对象通过Message的replyTo参数传递给server,服务端就可以通过这个replyTo参数就可以回应client了,这里略过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值