Android进程间通信之使用Messenger
2015-09-09 18:35
423 查看
Messenger,信使,可使用它进行进程间的通信,而Messenger对Service的请求采用队列的方式,因此它不支持多线程通信。
看看官方文档对于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传递给服务端。
服务端通过Messenger的getBinder方法将IBinder对象返给客户端,用于共享服务端的Messenger。
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): 客户端收到服务端发来的消息!
看看官方文档对于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; <a href="http://home.51cto.com/index.php?s=/space/5017954" target="_blank">@Override</a> protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBindBtn = (Button) findViewById(R.id.bind_service); mBindBtn.setOnClickListener(new OnClickListener() { 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() { 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() { public void onServiceDisconnected(ComponentName name) { Log.v(TAG, "服务已断开"); isBindService = false; mClientMessenger = null; } 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() { 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); 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): 客户端收到服务端发来的消息!
相关文章推荐
- Android客户端支付宝支付
- Android入门之网络图片查看器
- Android广播传值
- Android 读取工程中的txt文件
- android中MVP模式
- DrawerLayout 抽屉效果
- web页面在android上显示bug处理
- android 地图开发之聚合,定位
- 细数Android开源项目中那些频繁使用的并发库中的类
- android 中 LocalSocket的基本使用方法
- 【Android】状态栏通知Notification、NotificationManager详解
- android listview添加footview,有的手机可以正常显示,有的则不显示
- ViewPager 详解
- Android屏幕密度
- 在 Android Studio 中使用OpenCV所遇到问题
- Android ViewPager多页面滑动切换以及动画效果
- Android ViewPager和Fragment实现顶部导航界面滑动效果
- android存储数据的四种方式
- Android 调用手机浏览器[小记]
- android五种布局的基本使用