android进程通信之Messenger

写在前面的话

前面我写了一篇文章—android学习之remote service 的aidl详解,讲到跨进程多线程通信,我们使用aidl技术来实现。但是平时我们可能只要要求跨进程通信,而不需要使用多线程,那么这时候,Messenger就是我们的一个非常好的选择。

Messenger实例

Server端:

MessengerService.java

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;
import android.widget.Toast;

public class MessengerService extends Service {

    public static final String TAG = "MessengerService";

    public static final int MSG_SEND_TO_SERVER = 1;
    public static final int MSG__REPLY_FROM_SERVER = 2;

    final Messenger mMessenger = new Messenger(new IncomingHandler());

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SEND_TO_SERVER:
                    Log.i(TAG, "MSG_SEND_TO_SERVER:"+"--msg.arg1:"+msg.arg1+"--msg.arg2:"+msg.arg2);
                    try {
                        Message messageReplyToClient = new Message();
                        messageReplyToClient.what = MSG__REPLY_FROM_SERVER;
                        messageReplyToClient.arg1 = msg.arg2;
                        messageReplyToClient.arg2 = msg.arg1;
                        msg.replyTo.send(messageReplyToClient);
                    } catch (RemoteException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}

Client端

MainActivity.java

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;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;

public class MainActivity extends Activity {

    public static final String TAG = "MainActivity";
    public static final int MSG_SEND_TO_SERVER = 1;
    public static final int MSG__REPLY_FROM_SERVER = 2;
    private Messenger mMessenger;
    boolean mBound;
    private TextView textViewShowConnectState;
    private TextView textViewMessageSendToService;
    private TextView textViewMessageReceiverFromService;
    private Button button;

    private Messenger mMessengerReceive = new Messenger(new MyHandler());
    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG__REPLY_FROM_SERVER:
                    Log.i(TAG, "MSG__REPLY_FROM_SERVER:"+"--msg.arg1="+msg.arg1+"--msg.arg2="+msg.arg2);
                    textViewMessageReceiverFromService.setText("msg:server-->client:"+"--msg.arg1="+msg.arg1+"--msg.arg2="+msg.arg2);
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mMessenger = new Messenger(service);
            mBound = true;
            textViewShowConnectState.setText("service connect");
        }

        public void onServiceDisconnected(ComponentName className) {
            mMessenger = null;
            mBound = false;
            textViewShowConnectState.setText("service disconnect");
        }
    };

    public void sendMessage(View v) {
        if (!mBound) return;
        // Create and send a message to the service, using a supported ‘what‘ value
        int arg1 = (int) (Math.random() * 100);;
        int arg2 = (int) (Math.random() * 100);;
        Message msg = Message.obtain(null, MSG_SEND_TO_SERVER, arg1, arg2);
        msg.replyTo = mMessengerReceive;
        textViewMessageSendToService.setText("msg:client-->server:"+"--msg.arg1="+msg.arg1+"--msg.arg2="+msg.arg2);
        try {
            mMessenger.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    private void init() {
        // TODO Auto-generated method stub
        textViewShowConnectState = (TextView)findViewById(R.id.textViewShowConnectState);
        textViewMessageSendToService = (TextView)findViewById(R.id.textViewMessageSendToService);
        textViewMessageReceiverFromService = (TextView)findViewById(R.id.textViewMessageReceiverFromService);
        button = (Button)findViewById(R.id.button);
    }

    @Override
    protected void onStart() {
        super.onStart();
        bindService(new Intent("com.android.ACTION.MessengerService"), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }

}

我们Client给Server发送消息的是封装在sendMessage方法中的:

mMessenger.send(msg);

那么如何响应从server端回传的消息了,这中间的关键是把client发送到server的消息msg与回调处理的Messenger mMessengerReceive相关联:

msg.replyTo = mMessengerReceive;

布局文件:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textViewShowConnectState"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/textViewShowConnectState"
        android:onClick="sendMessage"
        android:text="click send message to Server"
        />

    <TextView
        android:id="@+id/textViewMessageSendToService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button"/>

    <TextView
        android:id="@+id/textViewMessageReceiverFromService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/textViewMessageSendToService"/>

</RelativeLayout>

效果图

从源码和效果图,我们可以看出,这个Demo是从Client发送一个消息到Server,Server把消息的msg.arg1和msg.arg2的值交换后再反馈给Client,Client将从Client发送到Server的消息和Server返回的消息都显示出来。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 20:39:18

android进程通信之Messenger的相关文章

Android进程通信之Messenger&amp;AIDL使用详解

1. 前言 提到的进程间通信(IPC:Inter-Process Communication),在Android系统中,一个进程是不能直接访问另一个进程的内存的,需要提供一些机制在不同的进程之间进行通信,Android官方推出了AIDL(Android Interface Definition Language),它是基于Binder机制的,至于官方为什么要采用Binder,查看为什么Android要采用Binder作为IPC机制,分析很全面. 上篇Android之Service的细枝末节提到组

跨进程通信之Messenger

1.简介 Messenger,顾名思义即为信使,通过它可以在不同进程中传递Message对象,通过在Message中放入我们需要的入局,就可以轻松实现数据的跨进程传递了.Messenger是一种轻量级的IPC方案,其底层实现是AIDL. Messenger的使用方法很简单,它对AIDL进程了封装,并且由于它一次只处理一个请求,因此在服务端我们不需要考虑同步的问题. 2.实现跨进程通信 1)服务端进程 首先我们需要在服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler并通

Android 进程通信机制之 AIDL

什么是 AIDL AIDL 全称 Android Interface Definition Language,即 安卓接口描述语言.听起来很深奥,其实它的本质就是生成进程间通信接口的辅助工具.它的存在形式是一种 .aidl 文件,开发者需要做的就是在该文件中定义进程间通信的接口,编译的时候 IDE 就会根据我们的 .aidl 接口文件生成可供项目使用的 .java 文件,这和我们说的"语法糖"有些类似. AIDL 的语法就是 java 的语法,就是导包上有点细微差别.java 中如果两

Android进程通信:AIDL入门实例

AIDL即 Android Interface Definition Language.原因:On Android, one process cannot normally access thememory of another process. 也就是说AIDL用于android进程间通信,下面就记录一下第一个aidl的demo. 官方文档也给出了基本的使用方法,如下图: 1. 在android项目的src相关包下创建一个aidl文件 IRemoteService.aidl: package

Android进程间的通信之Messenger

Android进程间的通信方式可以通过以下两种方式完成: 1 Android接口定义语言(AIDL) 2 使用Messenger绑定服务 本文我们将学习使用Messenger绑定服务的方式进行进程间的通信. Android AIDL和Messenger区别 使用Messenger是执行进程间通信最简单的方法,因为Messenger会在单一线程中创建包含所有请求的队列,这样您就不必对服务进行线程安全设计.而纯粹的AIDL接口会同时向服务发送多个请求,服务随后必须应对多线程处理.AIDL通常应用在服

Android基础——Messenger在跨进程通信中的使用

Messenger在跨进程通信中的使用 事先说明: 本人也是个初学者,所以本文是从初学者的角度入手,如果有不妥的地方请留言教导我,谢谢. 本篇文章主要针对讲解Messenger的使用和Messenger在应用层上的原理解析和Messenger在服务端的回复. 什么是Messenger? Messenger可以翻译为信使,Messenger是一种轻量级的IPC方案,通过它可以在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以实现数据的进程间传递了. 步骤一:Mes

Android进阶笔记04:Android进程间通讯之Messenger ( 区别于AIDL)

一. Android进程间通讯之Messenger 的引入 (1)引言:      平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进程间通讯.它是基于消息的进程间通信,就像子线程和UI线程发送消息那样,是不是很简单,还不用去写AIDL文件,是不是有点小爽.哈哈.此外,还支持记录客户端对象的Messenger,然后可以实现一对多的通信:甚至作为一个转接处,任意两个进程都能通过服务端进行通信. (2) Messenger 与 AIDL 比较:    

Android Service IPC通信之Messenger机制

概述 之前我写过一篇博客介绍Service:Android Service全面解析,里面讲过如何实现Service的跨进程(IPC)通信,主要是通过编写AIDL接口文件来实现的.本篇我们来讲讲Service IPC通信的另外一种方式-Messenger. Messenger,也称为信使,通过它可以在不同的进程间传递message对象,在message中放入我们需要传递的数据你就可以实现跨进程通信和传递数据了.所以说Messenger机制是基于消息的跨进程通信方式. 可以看到,我们可以在客户端发送

Android进程间的通信之AIDL

Android服务被设计用来执行很多操作,比如说,可以执行运行时间长的耗时操作,比较耗时的网络操作,甚至是在一个单独进程中的永不会结束的操作.实现这些操作之一是通过Android接口定义语言(AIDL)来完成的.AIDL被设计用来执行进程间通信,另一种实现方式见博文Android进程间的通信之Messenger.本文我们将学习如何创建AIDL文件实现Android进程间通信.在正式学习之前,我们先澄清一些"事实". 关于Android Service 1.Android服务不是后台任务