Android基础——Service IPC通讯(Messenger实现)

来源:互联网 发布:海牙国际军事法庭 知乎 编辑:程序博客网 时间:2024/06/05 00:20

Messager实现IPC通信,底层也是使用了AIDL方式。和AIDL方式不同的是,Messager方式是利用Handler形式处理,因此,它是线程安全的,这也表示它不支持并发处理;而AIDL方式是非线程安全的,支持并发处理,因此,我们使用AIDL方式时需要保证代码的线程安全。大部分情况下,我们应用中不需要并发处理。因此,我们通常只需要使用Messager方式。

在我们的例子中:ClientActivity和Service分数不同的进程,我们在Client绑定Service的时候可以获得Service端的Messenger,在Client端通过Messenger发送消息到Service端,将消息交给handler 去处理,同样Service端也可以通过Client端的Messenger进行同样的操作。

为了让Service运行在其他的进程,我们需要在Manifest.xml中做一些设置:

<service            android:name="com.flyingduck.servicedemo2.MessengerService"            android:process=":remote" >        </service>
android:name=“:remote”写法是任意的,可以写成其他的字符串,但是必须要加上‘:’的前缀。

客户端进程:

package com.flyingduck.servicedemo2;import android.app.Activity;import android.app.Service;import android.content.ComponentName;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.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class ClientActivity extends Activity {private TextView showTxt;private Button sendMsg;private Button boundBtn;private Button unboundBtn;private ServiceConnection conn;private final Messenger mMessenger = new Messenger(new IncomingHandler());/** 服务端的Messenger **/private Messenger serviceMessenger;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_client);showTxt = (TextView) findViewById(R.id.show_message);sendMsg = (Button) findViewById(R.id.send_set_value_message);boundBtn = (Button) findViewById(R.id.bound_service);unboundBtn = (Button) findViewById(R.id.unbound_service);boundBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {doInBindService();}});unboundBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {doInUnBindService();}});sendMsg.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {showTxt.setText("send set_value_message");if (serviceMessenger != null) {try {// 发送一个100 值到serviceMessage msg = Message.obtain(null,MessengerService.MSG_SET_VALUE, 100, 0);msg.replyTo = mMessenger;serviceMessenger.send(msg);} catch (RemoteException e) {e.printStackTrace();}}}});conn = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {showTxt.setText("disconnectes");}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {serviceMessenger = new Messenger(service);showTxt.setText("connectes");try {Message msg = Message.obtain(null,MessengerService.MSG_REGISTER_CLIENT);msg.replyTo = mMessenger;serviceMessenger.send(msg);} catch (RemoteException e) {e.printStackTrace();}}};}private void doInBindService() {showTxt.setText("bind");bindService(new Intent(this, MessengerService.class), conn,Service.BIND_AUTO_CREATE);}private void doInUnBindService() {showTxt.setText("unbind");unbindService(conn);if (serviceMessenger != null) {try {Message msg = Message.obtain(null,MessengerService.MSG_UNREGISTER_CLIENT);msg.replyTo = mMessenger;serviceMessenger.send(msg);} catch (RemoteException e) {e.printStackTrace();}}}/** 用于处理服务发过来的消息 **/class IncomingHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MessengerService.MSG_SET_VALUE:showTxt.setText("received from service:" + msg.arg1);break;default:super.handleMessage(msg);}}}}



Service端:

package com.flyingduck.servicedemo2;import java.util.ArrayList;import android.app.Notification;import android.app.NotificationManager;import android.app.Service;import android.content.Context;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.widget.Toast;public class MessengerService extends Service {private NotificationManager notifyM;/** 用于记录所有绑定service的客户端 这里只有一个client绑定这个service**/ArrayList<Messenger> clients = new ArrayList<Messenger>();private final Messenger mMessenger = new Messenger(new IncomingHandler());/** 定义几种Handler的消息类型 **/static final int MSG_REGISTER_CLIENT = 1;static final int MSG_UNREGISTER_CLIENT = 2;static final int MSG_SET_VALUE = 3;/** 用于发送消息时使用 **/private int value = 100;/** 用于处理客户端发过来的消息 **/class IncomingHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_REGISTER_CLIENT:clients.add(msg.replyTo);break;case MSG_UNREGISTER_CLIENT:clients.remove(msg.replyTo);break;case MSG_SET_VALUE:for (int index = clients.size() - 1; index >= 0; index--) {try {//接收到ClientActivity发送过来的值“100”,再加上value ,发送给ActivityClientclients.get(index).send(Message.obtain(null, MSG_SET_VALUE, value+msg.arg1, 0));} catch (RemoteException e) {clients.remove(index);}}break;default:super.handleMessage(msg);break;}}}@Overridepublic void onCreate() {notifyM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);showNotification();}@Overridepublic IBinder onBind(Intent intent) {return mMessenger.getBinder();}private void onDestor() {notifyM.cancel(100);Toast.makeText(this, "service distory", Toast.LENGTH_SHORT).show();}private void showNotification() {Notification notification = new Notification(R.drawable.ic_launcher,"Service start...", System.currentTimeMillis());notification.setLatestEventInfo(this, "content-title","service started", null);notifyM.notify(100, notification);}}


client 发送了一个100整数给service端,service将其加上100发送给client端显示。

运行截图:



原创粉丝点击