Android IPC之Messager用法示例

Messager可以翻译为信使,顾名思义,通过它可以在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间穿传递了。Messager是一种轻量级的IPC方式,它的底层实现是AIDL。这个大家可以下去看一下Messager的构造方法就知道了。
Messager的使用方法很简单,它对AIDL做了封装,使得我们可以更简便的进行进程间通信。同时,由于它一次处理一个请求,因此在服务器中不存在并发的情形。实现一个Messager有如下几个步骤,分为服务端和客户端。
1,服务端进程
首先,我们需要在服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messager对象,然后在Service的onBinder中返回这个Messager对象底层的Binder即可。

代码如下:
package com.example.lenovo.textmyaidl;

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

/** * MessaerHandler用来处理客户端发来的消息,并从消息中取出客户端发来的文本消息。而 * messenger是一个Messager对象,它和MessaerHandler相关联,并在onBind方法中返回它里面的Binder * 对象,可以看出这里的messager的作用就是将客户端发送的消息传递给MessaerHandler处理。 * Created by lenovo on 2016/4/24. */
public class MessengerService extends Service {

    private  static  final String TAG = "MessengerService";

    private static class MessaerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MyContants.MSG_FROM_CLIENT:
                    Log.e(TAG,"receive msg from client:"+msg.getData().getString("msg"));
                    Messenger client = msg.replyTo;
                    Message replyMessage = Message.obtain(null,MyContants.MSG_FROM_SERVICE);
                    Bundle bundle = new Bundle();
                    bundle.putString("reply","嗯,你的消息我收到了,稍后回复你!");
                    replyMessage.setData(bundle);
                    try {
                        client.send(replyMessage);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;

            }
        }
    }
    private final Messenger messenger = new Messenger(new MessaerHandler());
    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }
}

然后,注册service,让其运行在单独的进程中:

<service android:name=".MessengerService" android:process=":remote"></service>

2,客户端进程

代码如下:

package com.example.lenovo.textmyaidl;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
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 MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    private  Messenger mGetMessage = new Messenger(new MessengerHandler());
    private Messenger mService;

    private  static class MessengerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what){
                case MyContants.MSG_FROM_SERVICE:
                    Log.e(TAG,"recive msg from Service:"+msg.getData().getString("reply"));
            }
        }
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = new Messenger(service);
            Message msg = Message.obtain(null,MyContants.MSG_FROM_CLIENT);
            Bundle data = new Bundle();
            data.putString("msg","hello,this is client");
            msg.replyTo = mGetMessage;
            msg.setData(data);
            try {
                mService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this,MessengerService.class);
        bindService(intent,connection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        unbindService(connection);
        super.onDestroy();
    }
}

运行结果:

04-24 11:31:38.632 12385-12385/com.example.lenovo.textmyaidl:remote E/MessengerService: 
receive msg from client:
hello,this is client
04-24 11:31:39.060 12363-12363/com.example.lenovo.textmyaidl E/MainActivity: recive msg from Service:
嗯,你的消息我收到了,稍后回复你!

通过上面的例子可以看出来。在Messenger中进行数据传递必须将数据封装到Messenge中。Messenger和Messenge都实现了Parcelable接口,因此可以跨进程传输。简单的来说就是Messenge中所支持的数据类型就是Messenger所支持的传输类型。Messenge的另一个字段object在同一个进程中是很实用的,但是在跨进程中却是由有很大的限制的,只支持系统提供的实现了Parcelable接口的对象的传输,非系统的(自定义的)对象是无法跨进程用object字段来传输的。

你可能感兴趣的:(android,ipc)