android—进程间通信之Messenger

来源:互联网 发布:怎样备份软件数据 编辑:程序博客网 时间:2024/05/15 13:51

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了,这里略过。

0 0