android传递数据,安卓手机之间传数据
android 组件间、进程间数据传输和限制
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、匿名共享内存()
Android 页面之间数据传递方式有几种
对于依赖于操作系统的程序,客户程序除了包含一个程序入口外,还需要和相关系统服务一起运行,以完成指定的任务。比如,Win32程序需要和GUI系统服务一起实现带有可视窗口的功能;X
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之间传递数据也不是必需的。
Android Intent传递大量数据造成页面卡顿,闪退的解决方案
我们知道在Activity间使用Intent传递List含有大量序列化的对象的时候,或者传递较大bitmap等较大量数据的时候会引起页面卡顿。而且Android本身也限制了能够传递的数据大小在1MB左右。这就要求我们不得不为传输大量数据寻求一个解决方法。
通常我们可以想到的一个方法是当从A页面跳转至B页面的时候将需要传递的大对象赋值给A页面的一个静态变量,在B页面去取A页面的值。这种方式简单却有很多问题,比如可能会有很多其他页面访问B页面这会导致静态变量管理混乱,而且如果在组件化开发的过程中,需要进行组件间跳转的时候只能把这种静态变量写在BaseLibrary中,这显然是不够友好的。
我们稍加处理做一个简单的封装。++参考:《Android工程化最佳实践》++
就这样简单的两个类我们就完成了封装,可以看到在Model中序列化了一个int值。下面我们来看一个简单的使用示例:
通过以上方式的封装,可以看到无论需要序列化传递的对象有多大,在传值的时候只是传递了一个“int”而已。使用该这种方法时需要注意的一点是在数据的接收页面只能使用getIntent()获取一次该对象的值,因为我们在取完一次值后便将该对象从缓存区移除了。
Android跨进程传递大数据
最近要从 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 :
发送
接收:
android中使用什么在组件中传递数据信息
Intent(意图)主要是解决Android应用的各项组件之间的通讯。 为了实现传递数据这个目的需要以下步骤 Activity1需要构造一个 Intent,这个Intent用于告诉系统,我们要做“查看”动作 intent可调用putExtra来存放想要传递的数据 然后调用setClass,设置Activity1和欲调用的组件Activity2 最后调用startActivity将构造的Intent传入,系统会根据此Intent中的描述,到Activity1中找到满足此Intent要求的Activity,系统会调用找到的 Activity2最终传入Intent 在Activity2中可使用getIntent来获取传递的Intent,并通过获取数据的方法来获取数据 代码示例: Intent intent = new Intent(); // Activity1intent.putExtra("one", num1); intent.putExtra("two", num2); intent.setClass(FirstActivity.this, SecondActivity.class); startActivity(intent); Intent intent = getIntent(); //Activity2String num1 = intent.getStringExtra("one"); String num2 = intent.getStringExtra("two"); int ret = Integer.parseInt(num1) + Integer.parseInt(num2); result.setText(ret+"");注意:我们在使用intent的时候可以使用bundle传递复制的数据类型。
本文名称:android传递数据,安卓手机之间传数据
浏览路径:http://hbruida.cn/article/phjcpj.html