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方式对外提供是最好的了。