扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
对于依赖于操作系统的程序,客户程序除了包含一个程序入口外,还需要和相关系统服务一起运行,以完成指定的任务。比如,Win32程序需要和GUI系统服务一起实现带有可视窗口的功能;X
和政ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:13518219792(备注:SSL证书合作)期待与您的合作!
Window程序也需要和X
Window
Server一起实现窗口功能。
程序员需要在不同的Activity之间传递数据,然而,这个问题本身就有问题。所谓传递消息一般是指多个线程之间,而Activity本身并不是线程,ActivityThread才是一个线程,即UI线程。同一个程序中的多个Activity都由ActivityThread进行调用,Activity本身只是一个Java类而已,就像Rect、Trigle类一样,如果有人问Rect类和Trigle类之间如何传递消息,你会不会觉得有点奇怪?
事实上,如果要在两个类中传递数据,方法可以有很多。
方法一:可以先实例化某个类,获得该类的引用,当其他类需要该对象的内部数据时,可以直接通过该引用去访问该类的内部数据。
方法二:对于A、B两个类之间,可以先实例化一个第三方类C,然后两个类都可以把需要传递的数据存入C中,或从C中取出。
这些方法理论上都可以用在Activity类之间传递数据。然而,与普通类传递数据有所不同,普通类的实例化都是程序员显式完成的,而Activity类的实例化却是由Framework完成的,程序员只能使用startActivity()方法来告诉Framework去运行哪个Activity,这就意味着程序员不能得到Acitivity对象的引用,那么就不能直接访问该对象的内部数据。解决的办法是使用Activity.getApplication()函数,该函数能够返回一个Application对象,该Application对象在该程序中是唯一的,同一程序中的不同Activity调用该函数所返回的Application对象是相同的,该对象的名称可以在AndroidManifest.xml中指定。一旦获取了该Application对象,就可以借助该对象,在不同的Activity之间传递数据。
除此之外,Framework本身也提供了标准的Activity之间传递数据的方法,即Intent类。该类作为startActivity()的参数,仅用于在启动Activity时传递给目标Activity,同时,如果调用startActivityForResult(),目标Activity在结束后,也会返回一个Intent对象给原Activity。
另外,从设计理念的角度来看,Android认为,两个Activity如果要共享数据,可以通过Preference
Storage或者文件、数据库进行,同时,在一般情况下,设备上只会有一个Activity在运行,因此,多个Activity之间传递数据也不是必需的。
最近要从 Service 端给 Client 端传递图片数据,之前的数据都是通过 aidl 传递:
创建 Parcelable 文件
ImageData.java
test.aidl
运行报错:
这里导致 DeadObjectException 的原因主要是 binder 创建的 buffer 被占满了:
传输中如果数据大于 free_buffers ,则会抛出 DeadObjectException
socke 传输不受大小限制,但实现比较复杂
通过文件传输比较简单,但效率差,而且高版本会受到Android系统权限限制
将较大数据切割成较小的数据传输,此方法是兼顾效率,复杂度较好的方案
定义数据体:
切割数据方法:
将ImageData按顺序构建发送:
client接收:
binder 本身也是利用 mmap ,可以利用实现 mmap 的框架,比如 MMKV
如果传输的数据是 Bitmap ,还可以用 Bundle 的 putBinder 方案
定义 binder :
发送
接收:
1、Bunder 传递对象为什么需要序列化?
1》因为 bundle 传递数据时只支持基本数据类型,所以在传递对象时需要序列化转
换成可存储或可传输的本质状态(字节流)。序列化后的对象可以在网络、IPC
(比如启动另一个进程的 Activity、Service 和 Reciver)之间进行传输,也可以 存储到本地。
2》序列化,表示将一个对象转换成可存储或可传输的状态。序列化的原因基本三种 情况:
1.永久性保存对象,保存对象的字节序列到本地文件中; 2.对象在网络中传递;
3.对象在 IPC 间传递。
2、序列化Serializable 和Parcelable 的区别
Serializable(Java 自带):
1》Serializable 是序列化的意思,表示将一个对象转换成存储或可传输的状态。序列化后的对象可以在网络上进传输,也可以存储到本地。
2》Serializable 会使用反射,序列化和反序列化过程需要大量 I/O 操作。
Parcelable(android 专用):
1》除了 Serializable 之外,使用 Parcelable 也可以实现相同的效果,不过不同于将 对象进行序列化,Parcelable 方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是 Intent 所支持的数据类型,这也就实现传递对象的功能 了。
2》Parcelable 自已实现封送和解封(marshalled unmarshalled)操作不需要用反 射,数据也存放在 Native 内存中,效率要快很多。
两者最大的区别在于 存储媒介的不同,Serializable 使用 I/O 读写存储在硬盘 上,而 Parcelable 是直接 在内存中读写。很明显,内存的读写速度通常大于 IO 读写,所以在 Android 中传递数据优先选择 Parcelable。
3、bundle传输的数据是否有限制,是多少,为什么要限制?
1》Intent 在传递数据时是有大小限制的,大约限制在 1MB 之内,你用 Intent 传递 数据,实际上走的是跨进程通信(IPC),跨进程通信需要把数据从内核 copy到进程中,每一个进程有一个接收内核数据的缓冲区,默认是 1M;如果一次传 递的数据超过限制,就会出现异常。
2》不同厂商表现不一样有可能是厂商修改了此限制的大小,也可能同样的对象在不 同的机器上大小不一样。
3》传递大数据,不应该用 Intent;考虑使用 ContentProvider 或者直接匿名共享内 存。简单情况下可以考虑分段传输。
4、匿名共享内存()
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流