Android使用Messenger实现进程间通信

来源:互联网 发布:windows核心编程第5版 编辑:程序博客网 时间:2024/06/05 10:13

Messenger是一种轻量级的IPC方案,在进程间传送Message对象,Message中可以传送Bundle对象,Bundle中可以传送我们实现了Parcelable接口的对象。使用Messenger不会出现并发读写问题,因为Messenger是以串行方式工作的,所以如果有大量的请求,不适合使用Messenger。

Messenger有两个构造方法:

 //关联一个Handler public Messenger(Handler target)  //关联一个IBinder public Messenger(IBinder target)

核心思路:

1.客户端与服务器都要有自己的Messenger并且关联一个Handler

2.服务端:将mServiceMessenger通过getBinder将IBinder传递给客户端

3.客户端:通过 public Messenger(IBinder target)构造方法获得服务器的mServiceMessenger,使用mServiceMessenger.send给服务器发送消息,并且在msg中把客户端的mClientMessenger带到服务器

4.服务端:服务器在Handler中接收到msg并且拿到客户端的mClientMessenger,使用mClientMessenger.send给客户端发送消息

这里写图片描述

客户端代码:

public class MainActivity extends Activity {    private static final int MSG_FROM_CLIENT = 0;    private static final int MSG_FROM_SERVICE = 1;    private ServiceConnection conn;    private Messenger mServiceMessenger;    private Button mButton;    //mClientHandler    private Handler mClientHandler = new Handler(){        public void handleMessage(Message msgFromService) {            switch (msgFromService.what) {            case MSG_FROM_SERVICE:                Log.i("zhangqi", "客户端:"+msgFromService.getData().getString("service_msg"));                break;            }        };    };    //mClientMessenger    private Messenger mClientMessenger = new Messenger(mClientHandler);    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mButton = (Button) findViewById(R.id.button);        Intent intent = new Intent(this,MyService.class);        conn = new ServiceConnection() {            @Override            public void onServiceDisconnected(ComponentName name) {            }            @Override            public void onServiceConnected(ComponentName name, IBinder iBinder) {                //拿到服务器传给客户端的IBinder,通过new Messenger(service)拿到mServiceMessenger                mServiceMessenger = new Messenger(iBinder);                //Messenger传递的是Message,实例化一个Message                Message msgFromClient = Message.obtain(null, MSG_FROM_CLIENT);                //Message传递的是Bundle                Bundle bundle = new Bundle();                //发送一个String类型的数据                bundle.putString("client_msg", "这里是客户端,呼叫服务器");                msgFromClient.setData(bundle);                //一定不要忘了将mClientMessenger带到服务器去                msgFromClient.replyTo = mClientMessenger;                try {                    //调用mServiceMessenger.send将消息发送的服务器                    mServiceMessenger.send(msgFromClient);                } catch (RemoteException e) {                    e.printStackTrace();                }            }        };        //绑定Service        bindService(intent, conn, BIND_AUTO_CREATE);        //点击按钮发送客户端请求        mButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //由于在onServiceConnected中我们已经拿到了mServiceMessenger了,再发送消息的时候                //直接新建Message对象就可以了,最后调用mServiceMessenger将消息发送给服务器                Message msgFromClient = Message.obtain(null,MSG_FROM_CLIENT);                Bundle bundle = new Bundle();                bundle.putString("client_msg", "客户端发起一次请求");                msgFromClient.setData(bundle);                msgFromClient.replyTo = mClientMessenger;                try {                    mServiceMessenger.send(msgFromClient);                } catch (RemoteException e) {                    e.printStackTrace();                }            }        });    }    @Override    protected void onDestroy() {        super.onDestroy();        //解绑Service        unbindService(conn);        conn = null;    }}

服务端代码:

public class MyService extends Service{    private static final int MSG_FROM_CLIENT = 0;    private static final int MSG_FROM_SERVICE = 1;    // mServiceHandler    private Handler mServiceHandler = new Handler(){        public void handleMessage(android.os.Message msgFromClient) {            switch (msgFromClient.what) {            case MSG_FROM_CLIENT:                //拿到客户端发来的消息                Log.i("zhangqi", "服务器:"+msgFromClient.getData().getString("client_msg"));                //拿到客户端的mClientMessenger                Messenger mClientMessenger = msgFromClient.replyTo;                //Messenger传递的是Message,所以新建一个Message实例                Message msgFromService = Message.obtain(null,MSG_FROM_SERVICE);                //Message传递的是Bundle                Bundle bundle = new Bundle();                //发送一个String类型的数据                bundle.putString("service_msg", "这里是服务器,收到客户端请求");                msgFromService.setData(bundle);                try {                    //调用mClientMessenger.send将消息发送给客户端                    mClientMessenger.send(msgFromService);                } catch (RemoteException e) {                    e.printStackTrace();                }                break;            }        };    };    // mServiceMessenger关联mServiceHandler    private Messenger mServiceMessenger = new Messenger(mServiceHandler);    @Override    public IBinder onBind(Intent intent) {        //将IBinder传给客户端,客户端通过new Messenger(IBinder)拿到mServiceMessenger;        return mServiceMessenger.getBinder();    }}

将服务端Service运行在单独的进程

在AndroidManifest.xml中注册Service并且指定android:process=”com.zhangqi.remote” 这样服务端Service就会运行在com.zhangqi.remote进程上,客户端运行在以包名命名的进程上
这里写图片描述

客户端发送一次请求,客户端就会回应:
这里写图片描述

5 0
原创粉丝点击