Android Bundle的妙用

            Android Bundle的妙用


    对于有一定Android开发经验的读者来说,都知道Bundle可以进行跨进程传递消息,当然只能传入小数据,至于为什么可以参见博客Android 通过Binder传输数据大小限制。今天有同事提出一个需求,就是有其它的应用想跨进程获取终端的一些终端特性,虽然我们已经封装了一个类提供了相关信息,但是外面的客户不想使用这个接口,因为这个类里面封装太多东西了,他们不想引入类似Json这种数据然后解析。那么就到了Bundle大显身手了。



Bundle简介

    查看了Bundle源码,并结合stackOverFlow资料,Bundle的实现方式如下:ArrayMap内部是使用两个数组进行数据存储,一个数组记录key的hash值,另一个数组记录value值,内部使用二分法对key进行排序,并使用二分法进行添加、删除、查找数据,因此它只适合于小数据量操作,在数据量较大的情况下它的性能将会退化。而HashMap内部则是数组+链表的结构,在数据量较少的情况下,HashMap的Entry Array比ArrayMap占用更多的内存。由于使用Bundle的场景大多数为小数据量,所以相比之下,使用ArrayMap保存数据在操作速度和内存占用上都具有优势,因此使用Bundle来传递数据,可以保证更快的速度和更少的内存占用



代码实现

package com.pax.blogproject;

import java.util.Arrays;

//这是原始数据类,实际不止如此,这个只是作为说明使用
public class BundleData {
    public byte byteData = 1;//客户只想获取该数据
    public short shortData = 1;

    public String stringData = "hello";
    public byte[] byteArrayData = { 0, 1, 1, 0 };

    @Override
    public String toString() {
        return "BundleData [byteData=" + byteData + ", shortData=" + shortData
                + ", stringData=" + stringData + ", byteArrayData="
                + Arrays.toString(byteArrayData) + "]";
    }

}

package com.pax.blogproject;

import java.lang.reflect.Field;

import android.os.Bundle;
import android.util.Log;

public class BundleManager {

    public static Bundle getBundleData() {

        Bundle bundle = new Bundle();
        BundleData mBundleData = new BundleData();
        try {
            Class<? extends BundleData> cls = mBundleData.getClass();
            Field[] fieldArr = cls.getFields();
            for (int i = 0; i < fieldArr.length; i++) {
                String name = fieldArr[i].getName();
                String type = fieldArr[i].getGenericType().toString();
                Log.e("TAG", "The type : " + type);
                if (type.equals("byte")) {
                    bundle.putByte(name, fieldArr[i].getByte(mBundleData));
                } else if (type.equals("class [B")) {
                    bundle.putByteArray(name,
                            (byte[]) fieldArr[i].get(mBundleData));
                } else if (type.equals("short")) {
                    bundle.putShort(name, fieldArr[i].getShort(mBundleData));
                } else if (type.equals("class java.lang.String")) {
                    bundle.putString(name,
                            (String) fieldArr[i].get(mBundleData));
                }
            }
            return bundle;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

}

    好了上面是我们将我们的数据类进行封装,然后以Bundle的形式对外提供,那么外面接口怎么使用了,形如下:

 Bundle mBundle = BundleManager.getBundleData();
 Log.d("TAG","byteData : " + mBundle.getByte("byteData"));
 Log.d("TAG","shortData : " + mBundle.getShort("shortData"));
 Log.d("TAG","stringData : " + mBundle.getString("stringData"));

我们来看下实际的运行效果:

D/TAG     ( 6468): byteData : 1
D/TAG     ( 6468): shortData : 1
D/TAG     ( 6468): stringData : hello


结语

    通过妙用Bundle我们可以将比较大的数据,转换成类似HashMap的获取方式,用什么就get什么,从而避免了引入不要的类文件或者第三方库什么的。那么将如上方法将数据存在Bundle里面然后以get方式对外提供是最好的了。

Android中使用Bundle传递参数的大小限制

发布了89 篇原创文章 · 获赞 92 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/tkwxty/article/details/103182988