【读书笔记】【Android 开发艺术探索】第 2 章 IPC 机制
来源:互联网 发布:虚拟局域网软件排行 编辑:程序博客网 时间:2024/05/22 18:15
一、基础知识
1.一些概念
IPC : Inter-process Communication 跨进程通信,是指两个进程之间进行数据交换的过程。
线程:线程是 CPU 调度的最小单元,同时线程是一种有限的系统资源。
进程:一般是指一个执行单元, 在 PC 和移动设备上指一个程序或者一个应用。 进程可以包含多个线程。
2. Android 中的多进程模式
(1).开启多进程模式
给四大组件在 AndroidManifest 中指定 android:process 属性,即可开启。
通过命令行 adb shell ps 可以看见进程信息。
(2).多进程模式的运行机制
系统会为每一个进程分配一个独立的虚拟机,不同的虚拟机在内存分配不同的地址空间。
使用多进程会造成的问题:
.静态成员和单例模式完成失效;
.线程同步机制完成失效;
.SharedPreferences 的可靠性下降;
.Application 会多次创建(因为运行同一个进程中的组件是属于同一个虚拟机和同一个 Application 的)
二、IPC 基础概念介绍
1、Serializable 接口
Serializable 是 Java 提供的一个接口,是一个空接口,为对象提供标准的序列化和反序列化操作;
serialVersionUID :
用来辅助序列化和反序列化过程的,原则上序列化后的数据中的 serialVersionUID 只有和当前类的 serialVersionUID 相同才能正常地被反序列化。
一般手动指定 serialVersionUID 的值,是因为反序列化时当前类有所改变时,系统会重新计算当前类的 hash 值,并把它赋值给 serialVersionUID ,这个时候当前类的 serialVersionUID 和反序列化的数据中的 serailVersionUID 不一致,会出现反序列化失败,程序会出现 crash。
注意事项:
.静态成员变量属于类而不属于对象,所以不会参与序列化过程;
.用 transient 关键字的成员变量不参与序列化过程。
2、Parcelable 接口
Interface for classes whose instance can be written to and restored from a Parcel. Classes implementing the Parcelableinterface must also have a non-null static field called CREATOR of the type implements Parcelable.Creator interface.
Serializable 与 Parcelable 的区别与选用
Serializable 开销大,序列化和反序列化过程需要大量的 I/O 操作,如果是存储在设备中,网络传输,一般使用 Serializable;
Parcelable 主要用在内存序列化上,是 Android 中的方法。
3、Binder
Binder 是 Android 中的一个类,它实现 IBinder 接口。从 IPC 的角度来说, Binder 是 Android 中的一种跨进程通讯方式。
Android 开发中, Binder 主要用在 Service 中,包括 AIDL 和 Messenger .
三、 Android 中的 IPC 方式
1、使用 Bundle
2、使用文件共享
序列化一个对象到系统文件中,同时从另一个进程中恢复这个对象。
发序列化得到的对象只是在内容上和序列化之前的对象是一样的,但它们本质上还是两个对象。
使用文件方式来共享数据对文件格式没有具体的要求,只要读写双方约定数据格式即可。但是这种方式会面临并发读写的局限性。
文件共享方式适合在对数据同步要求不高的进程之间进行通信,并且要处理并发读写的问题。
系统对 SharedPreference 的读写有一定的缓存,在多进程中,SP 面对高并发的读写访问会丢失数据,所以,尽量不要在进程间通信中使用 SP.
3、使用 Messenger
轻量级 IPC 方案,底层实现是 AIDL ,串行处理消息。
例子
服务端进程
public class MessengerService extends Service { private static final String TAG = "message"; private static class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case Constants.MSG_FROM_CLIENT: Log.i(TAG, "receive msg from Client : " + msg.getData().getString("msg")); // 回复客服端 Messenger client = msg.replyTo; Message replyMessage = Message.obtain(null, Constants.MSG_FROM_SERVICE); Bundle bundle = new Bundle(); bundle.putString("reply", "你的消息已收到"); replyMessage.setData(bundle); try { client.send(replyMessage); } catch (RemoteException e) { e.printStackTrace(); } break; default: break; } } } private final Messenger mMessenger = new Messenger(new MessengerHandler()); @Override public IBinder onBind(Intent intent) { return mMessenger.getBinder(); }}
public class MessengerActivity extends Activity { private static final String TAG = "message"; private Messenger mMessenger; private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler()); private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mMessenger = new Messenger(service); Message msg = Message.obtain(null, Constants.MSG_FROM_CLIENT); Bundle data = new Bundle(); data.putString("msg", "Hello, this is client."); msg.setData(data); msg.replyTo = mGetReplyMessenger; try { mMessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_messenger); Intent intent = new Intent(this, MessengerService.class); bindService(intent,mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { unbindService(mConnection); super.onDestroy(); } private static class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what){ case Constants.MSG_FROM_SERVICE: Log.i(TAG, "receive msg from Service : " + msg.getData().getString("reply")); break; default: super.handleMessage(msg); break; } } }}
4、使用 AIDL
使用 AIDL 比较复杂,这里掠过
5、使用 Socket
使用 Socket 通信,首先要声明权限
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
四、选用合适的 IPC 方式
0 0
- 【读书笔记】【Android 开发艺术探索】第 2 章 IPC 机制
- Android开发艺术探索读书笔记(第2章 IPC机制)
- Android开发艺术探索 第2章 IPC机制 读书笔记
- 《Android开发艺术探索》读书笔记 (2) 第2章 IPC机制
- 《Android开发艺术探索》读书笔记 (2) 第2章 IPC机制
- Android开发艺术探索读书笔记-IPC机制
- IPC机制 - Android开发艺术探索读书笔记(第二章)
- 《Android开发艺术探索》读书笔记——IPC机制
- 《Android 开发艺术探索》读书笔记六 IPC机制之Binder
- IPC机制(Android开发艺术探索读书笔记)
- Android开发艺术探索读书笔记(第10章 消息机制)
- 《Android开发艺术探索》读书笔记-第二章 IPC机制(未啃透)
- 第二章IPC机制(Android开发艺术探索)
- Android开发艺术探索笔记_第二章 IPC机制
- Android开发艺术探索--第二章IPC机制(1)
- 《Android开发艺术探索》第二章IPC机制小结
- 《Android 开发艺术探索》读书笔记四 IPC机制之Android中的多进程模式
- 【读书笔记】【Android开发艺术探索】第10章 Android 的消息机制
- HDOJ1008
- PCB设计小问题
- 获得经纬度通过函数传到后台处理
- 二叉树的所有路径,因为有些IDE不支持itoa方法,自定义的int->stringstream->string,
- Externalizable&&Serializable
- 【读书笔记】【Android 开发艺术探索】第 2 章 IPC 机制
- Excel Sheet Column Number
- 电路杂记
- linux文件合并,去重
- 【BZOJ3653】谈笑风生【主席树】【DFS序】
- hdu 5672(尺取法)
- 十二、图的遍历--(3)广度优先搜索算法
- EMC小资料
- C++ 基础知识复习 1