Activity之间传递大数据问题

时间:2021-03-22 00:05:04

Android开发人员都知道,Intent适用于在不同的Activity之间传递数据,包括参数、字符串、以及序列化的对象等。但是笔者所做的项目用到了使用Intent 传递Bitmap图片对象,图片的数据量相对来说是比较大的,那么intent能否胜任传递图片的任务呢?

首先很明显bitmap实现了Android中的Parcelable接口,可以序列化。因此理所当然能够通过intent传递,然而图片的大小有没有限制呢?

Bitmap

extends Object

implements Parcelable

答案是肯定的,Intent在传递数据时是有大小限制的,这里官方并未详细说明,不过通过实验的方法可以测出数据应该被限制在1MB之内(1024KB),笔者采用的是传递Bitmap的方法,发现当图片大小超过1024(准确地说是1020左右)的时候,程序就会出现闪退、停止运行等异常(不同的手机反应不同),因此可以判断Intent的传输容量在1MB之内。

在Activity或者组件之前传递信息时,一般采用intent绑定bundle的方式传值,但在使用过程中需要注意的是不要用bundle传递大容量数据:

传输一般的数据参数不会用到这么大的数据量,因此intent符合除图片之外的大部分使用场景,请放心使用吧。如果想传递图片那么建议使用其他方式,附录里提供了三种传递图片的方式。

下面谈谈我们如何通过Intent组件传递大数据


传递小的bitmap对象

1。MainActivity中包括一个ImageView;当我们点击ImageView时;把图片传递给另外一个Activity

  MainActivity的主要代码:

复制代码代码如下:


Intent intent=new Intent(MainActivity.this,TranActivity.class);

            intent.putExtra("bitmap", bitmap);

            startActivity(intent);

  biitmap是 在onCreate方法中获得的图片对象 bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

我们点击图片的时候,跳转到TranActivity中;并且传递一个Bitmap作为参数

而对于比较大的数据传递(笔者实验最好不要超过1M),解决的方法如下:

方法一:将需要传递的数据写在临时文件或者数据库中,再跳转到另外一个组件的时候再去读取这些数据信息,这种处理方式会由于读写文件较为耗时导致程序运行效率较低;

方法二:将需要传递的数据信息封装在一个静态的类中(注意当前组件和要跳转到的组件必须属于同一个进程,因为进程之间才能够共享数据),在当前组件中为类设置内容,然后再跳转到的组件中去取,这种处理方式效率很高,但是会破坏程序的独立性。

最后附上传递图片的一些建议:

附1:Android中传递图片的三种方式:

1. 如果是本地res中的资源文件可以用intent.putExtra("id", R.id.xxx);传递一个对应的id过去。在新activity中通过id取出图片。getResources().getDrawable(R.id.xxx);

2. 如果不是本地资源文件或者adapter中没有存储id,可以把drawable转为bitmap,用intent.putExtra("bitmap", bitmap);传递过去。因为intent只能传递实现序列化的类,即继承java 的Serializable接口或者android的Parcelable接口。drawable没有实现该接口所以不能传递。

3. 如果是通过线程什么的从网上拉取的图片,可以定义一个下载的工具类,并定义一个static的静态Map集合,每拉取成功一张图片就把该图片存入Map中作为缓存。key是该图片的拉取地址。然后通过intent把地址传递过去。在新activity中通过该工具类取得静态map,并通过传递过来的地址中map中取出该图片。

附2:Android中获取bitmap尺寸的方法

在不同的API版本中该方法的实现方式不一样,总的来说可以使用一下方法分别适用于api19、api12和更早的api。获得数据的单位是字节,自行转化为KB或MB。

[java] view
plain
 copy
  1. public int getBitmapSize(Bitmap bitmap){
  2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){    //API 19
  3. return bitmap.getAllocationByteCount();
  4. }
  5. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1){//API 12
  6. return bitmap.getByteCount();
  7. }
  8. return bitmap.getRowBytes() * bitmap.getHeight();                //earlier version
  9. }