Android进程间通信之使用Messenger

来源:互联网 发布:无需备案的域名 编辑:程序博客网 时间:2024/05/16 09:08

Messenger,信使,可使用它进行进程间的通信,而MessengerService的请求采用队列的方式,因此它不支持多线程通信。

 

看看官方文档对于Messenger的解释:

 

Reference to a Handler, which others can use to send messages to it. This allows for the implementation of

message-based communication across processes, by creating a Messenger pointing to a Handler in one process,

and handing that Messenger to another process.

客户端和服务端可相互持有对方的Messenger来进行通信,下面我们来看看具体的实现。

在eclipse下创建两个工程,分别为客户端和服务端:


客户端的实现,创建客户端的Messenger,使用Messenger的构造方法指向一个handler实例,此handler用于处理服务端发过来的消息。

而客户端通过onServiceConnected获得服务端的Messenger,使用此Messenger给服务端发送消息,客户端的Messenger通过Message的replyTo传递给服务端。

public class MainActivity extends Activity {    private static final String TAG = "--DEBUG--";    // 用于启动service的ACTION    private static final String START_SERVER_ACTION = "com.young.server.START_SERVICE";    private static final int WHAT_ON_TO_SERVICE = 1;    private static final int WHAT_ON_TO_CLIENT = 2;    private Button mBindBtn;    private boolean isBindService = false;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mBindBtn = (Button) findViewById(R.id.bind_service);        mBindBtn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                bindService(new Intent(START_SERVER_ACTION), conn, Context.BIND_AUTO_CREATE);            }        });    }    // client端Handler,用于处理server端发来的消息    private Handler mClientHandler = new Handler(new Callback() {        @Override        public boolean handleMessage(Message msg) {            switch (msg.what) {            case WHAT_ON_TO_CLIENT:                Log.v(TAG, "客户端收到服务端发来的消息!");                break;            default:                break;            }            return false;        }    });    // client端Messenger    private Messenger mClientMessenger = new Messenger(mClientHandler);    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {            Log.v(TAG, "服务已断开");            isBindService = false;            mClientMessenger = null;        }        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            Log.v(TAG, "服务已链接");            isBindService = true;            // 获得server端信使Messenger实例            Messenger serverMessenger = new Messenger(service);            // 向server端发送的消息            Message toServerMessage = Message.obtain(null, WHAT_ON_TO_SERVICE);            // 通过replyTo把client端的信使传递给service            toServerMessage.replyTo = mClientMessenger;            try {                serverMessenger.send(toServerMessage);            } catch (RemoteException e) {                e.printStackTrace();            }        }    };    protected void onStop() {        if (isBindService)            unbindService(conn);        super.onStop();    };}

服务端Service的实现,服务端接收到客户端的消息以后,通过Message的replyTo取出客户端的Messenger,使用此Messenger给客户端发送消息,这就实现了进程之间的双向通信。

服务端通过Messenger的getBinder方法将IBinder对象返给客户端,用于共享服务端的Messenger。

public class RemoteService extends Service {    private static final String TAG = "--DEBUG--";    private static final int WHAT_ON_TO_SERVICE = 1;    private static final int WHAT_ON_TO_CLIENT = 2;    // server端handler,用来处理client发来的消息    private Handler mServerHandler = new Handler(new Callback() {        @Override        public boolean handleMessage(Message msg) {            switch (msg.what) {            case WHAT_ON_TO_SERVICE:                Log.v(TAG, "收到客户端发来的消息");                // server端获得client端的信使Messenger                Messenger clientMessenger = msg.replyTo;                Message toClientMsg = Message.obtain(null, WHAT_ON_TO_CLIENT);                try {                    // 使用客户端Messenger向客户端发送消息                    clientMessenger.send(toClientMsg);                } catch (RemoteException e) {                    e.printStackTrace();                }                break;            default:                break;            }            return false;        }    });    // server端信使Messenger    private Messenger mServerMessenger = new Messenger(mServerHandler);    @Override    public IBinder onBind(Intent intent) {        return mServerMessenger.getBinder();    }


再来看看服务端service的声明,因为要在其他进程中启动service,所以设置android:exported为true,此外还为service加入启动了权限。

<permission android:protectionLevel="normal" android:name="young.permission.START_SERVICE"></permission>    <service    android:name="com.young.server.RemoteService"    android:permission="young.permission.START_SERVICE"    android:exported="true" >    <intent-filter>        <action android:name="com.young.server.START_SERVICE" />    </intent-filter></service>


最后要在客户端添加相应的启动Service权限。

<uses-permission android:name="young.permission.START_SERVICE" />

程序运行后的结果,可以看到客户端和服务端都收到了对方发来的消息。

11-12 12:58:37.197: V/--DEBUG--(21322): 服务已链接
11-12 12:58:37.197: V/--DEBUG--(21268): 收到客户端发来的消息
11-12 12:58:37.197: V/--DEBUG--(21322): 客户端收到服务端发来的消息!

 

转自:http://www.cnblogs.com/virtual-young/p/4091955.html





0 0