Android 进程间通信,基于Messeger(IPC)
2016-05-27 15:40
507 查看
转载请注明出处:/article/11843093.html
Android 平台意义下的多进程开发一般也是指的一个应用程序(不同模块在不同进程)。
Messenger实现了IPC通信,其真实原理也是使用了AIDL进行通信,但是和直接使用AIDL不同的是Messenger利用了Handler处理通信,所以它是线程安全的(不支持并发处理);而我们平时用的AIDL是非线程安全的(支持并发处理)。所以大多数时候我们应用中是不需要处理夸进程并发处理通信的,所以这时选择Messenger会比AIDL更加容易操作。
工程的AndroidManifest.xml:
独立进程服务端Service代码:
客户端Activity代码:
运行程序,首先看下此时程序所拥有进程
执行
可以看到此时程序确实是两个进程
再看一下我们程序打印的log 消息信息
这就是一个超级简单的Messenger使用场景。(麻雀虽小,却也实现跨进程通信啊~~)
客户端的实现,创建客户端的Messenger,使用Messenger的构造方法指向一个handler实例,此handler用于处理服务端发过来的消息。
而客户端通过onServiceConnected获得服务端的Messenger,使用此Messenger给服务端发送消息,客户端的Messenger通过Message的replyTo传递给服务端。
服务端Service的实现,服务端接收到客户端的消息以后,通过Message的replyTo取出客户端的Messenger,使用此Messenger给客户端发送消息,这就实现了进程之间的双向通信。
服务端通过Messenger的getBinder方法将IBinder对象返给客户端,用于共享服务端的Messenger
github 源码下载:https://github.com/thinkparadox/Android-MessegerDemo.git
背景
Android 是基于linux内核的移动嵌入式设备。由于硬件的限制,导致cpu,内存等无法跟传统的pc相比。google 为了用户体验,对每个程序的使用内存做了限制(不同的开发厂商可能定制的内存大小不同),获取该数值大小:adb shell getprop | grep dalvik.vm.heapgrowthlimit
Android 平台意义下的多进程开发一般也是指的一个应用程序(不同模块在不同进程)。
Messenger实现了IPC通信,其真实原理也是使用了AIDL进行通信,但是和直接使用AIDL不同的是Messenger利用了Handler处理通信,所以它是线程安全的(不支持并发处理);而我们平时用的AIDL是非线程安全的(支持并发处理)。所以大多数时候我们应用中是不需要处理夸进程并发处理通信的,所以这时选择Messenger会比AIDL更加容易操作。
代码案例
整个Demo 核心流程是在主Activity的onCreat(客户端)中绑定位于不同进程的Service(服务端),绑定成功客户端会给服务Service 发送消息。整个过程是基于Messeger 以及Handler实现。工程的AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest package="com.listenread.luhuanju.messagermodel" xmlns:android="http://schemas.android.com/apk/res/android"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> //android:process=":remote" 为此service 指定不同的进程。":remote" 表示该进程是本应用的私有进程,外部不得访问。 <service android:name=".ServerService" android:process=":remote"/> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
独立进程服务端Service代码:
package com.listenread.luhuanju.messagermodel; import android.app.Service; import android.content.Intent; 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.support.annotation.Nullable; /** * Created by luhuanju on 16/5/27. * 服务器端的Service 处理客户端的链接请求 */ public class ServerService extends Service { private static final int MESSAGE = 0; private Messenger messenger = new Messenger(new MessengerHanlder()); private static class MessengerHanlder extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE: { //接收到客户端的消息 System.out.println(msg.getData().get("tag")); Message message = Message.obtain(null, 0); Bundle bundle = new Bundle(); bundle.putString("tag", "收到消息,这是回复"); message.setData(bundle); try { msg.replyTo.send(message); // msg.replyTo 返回的就是承载MESSAGE 消息的Messenger } catch (RemoteException e) { } break; } default: super.handleMessage(msg); } } } @Nullable @Override public IBinder onBind(Intent intent) { // return messenger.getBinder(); // } }
客户端Activity代码:
package com.listenread.luhuanju.messagermodel; import android.content.ComponentName; import android.content.Context; 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.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, ServerService.class); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } private Messenger messenger; private Messenger messengerToReply = new Messenger(new MessagerHanlder()); //客户端要回复消息,同样需要准备HANDLER private static class MessagerHanlder extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: System.out.println(msg.getData().get("tag")); break; default: super.handleMessage(msg); } } } /** * 绑定Service */ private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder iBinder) { //此SERVICE 是绑定成功之后,服务器返回的Ibinder messenger = new Messenger(iBinder); Message msg = Message.obtain(null, 0); Bundle bundle = new Bundle(); bundle.putString("tag", "i am client"); msg.setData(bundle); //注意此句 msg.replyTo = messengerToReply; try { messenger.send(msg); } catch (RemoteException e) { } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection); } }
运行程序,首先看下此时程序所拥有进程
执行
adb shell ps|grep (程序包名)com.listenread.luhuanju.messagermodel
可以看到此时程序确实是两个进程
再看一下我们程序打印的log 消息信息
这就是一个超级简单的Messenger使用场景。(麻雀虽小,却也实现跨进程通信啊~~)
总结
(此处借一张鸿神的一张图)客户端的实现,创建客户端的Messenger,使用Messenger的构造方法指向一个handler实例,此handler用于处理服务端发过来的消息。
而客户端通过onServiceConnected获得服务端的Messenger,使用此Messenger给服务端发送消息,客户端的Messenger通过Message的replyTo传递给服务端。
服务端Service的实现,服务端接收到客户端的消息以后,通过Message的replyTo取出客户端的Messenger,使用此Messenger给客户端发送消息,这就实现了进程之间的双向通信。
服务端通过Messenger的getBinder方法将IBinder对象返给客户端,用于共享服务端的Messenger
github 源码下载:https://github.com/thinkparadox/Android-MessegerDemo.git
相关文章推荐
- Windows下Cordova环境搭建及如何用android studio导入cordova项目生成apk
- PNG格式图片原理
- 【android随笔】工具类整理--两次点击BACK键,退出应用的实现
- Android视频播放器实现小窗口和全屏状态切换
- AndroidStudio 依赖 ButterKnife 出现的空指针异常
- Androin学习笔记五十七: Android 触摸手势基础 官方文档概览
- (2.2.8.5) Android proguard 详解和常见错误
- Android-PullToRefresh
- LruCache源码解析
- Android Dev Intro - Limits on setVisible of View
- Android开源项目分类汇总
- Android 设置头像——拍照获取图片保存图片进行广播
- Android的setVisibility(View.GONE)无效的问题及原因分析
- Android 状态保存 生命周期 onSaveInstanceState onRestoreInstanceState 方法
- Android系统组件之Activity的生命周期
- 向android程序中加入ios的表情字符
- Android中的Broadcast Action大全
- Android NDK环境搭建
- 模板方法的使用
- Scroller的fling方法详解