为什么要使用IntentDataHolder
- 避免使用原生的intent传递数据有字节数的限制,大概是不能超过1 M 字节
- 使用单例模式来统一在activity,receiver,service之间传递数据,可以传递任意大小的数据;
- 为避免内存溢出,value最多存活1分钟;需要在每次保存时清除1分钟前的value。
在一次项目中由于数据量过大导致Intent传递数据时爆出异常闪退,上网搜索之后发现可以使用IntentDataHolder来代替Intent来传递数据。
public class IntentDataHolder {
private static Map<Long, SoftReference<Object>> data = new HashMap<Long, SoftReference<Object>>();
private static Map<Long, Long> idMaps = new HashMap();//
private static int MAX_KEY_COUNT = 5;//为避免内存溢出,只允许存放最多5个值;
private static long MAX_ALIVE_TIME = 1 * 60 * 1000;//value最多存活1分钟;需要在每次保存时清除1分钟前的value。
public static void putExtra(Intent intent , String param,Object object){
Long callogRandomIds = RandomUtils.randomLong();
save(callogRandomIds,object);
intent.putExtra(param, callogRandomIds);
}
public static Object retrieve(Intent intent , String param){
Long calllogRandomIds = (Long)intent.getSerializableExtra(param);
if(hasKey(calllogRandomIds)){
return retrieve(calllogRandomIds);
}else {
return null;
}
}
public static void save(Long id, Object object) {
tidyData();
data.put(id, new SoftReference<Object>(object));
idMaps.put(System.currentTimeMillis(), id);
}
public static boolean hasKey(Long id) {
return data.containsKey(id);
}
private static Object retrieve(Long id) {
SoftReference<Object> objectSoftReference = data.get(id);
if(objectSoftReference!=null){
data.remove(id);
idMaps.remove(id);
return objectSoftReference.get();
}else {
return null;
}
}
/**
* 整理数据,清除1分钟以前的数据,清除id数目超过5的id数据;
*/
private static void tidyData() {
List<Long> keys = new ArrayList<>();
Iterator<Long> it = idMaps.keySet().iterator();
while (it.hasNext()){
Long key = it.next();
if (System.currentTimeMillis() - MAX_ALIVE_TIME > key) {
data.remove(idMaps.get(key));
it.remove();
} else {
keys.add(key);
}
}
if (keys.size() >= MAX_KEY_COUNT) {//剔除key的个数超过5的数据值;还是按照时间顺序;
Collections.sort(keys, new Comparator<Long>() {//升序排列;
@Override
public int compare(Long left, Long right) {
if (left > right) {
return 1;
} else if (left == right) {
return 0;
} else {
return -1;
}
}
});
Iterator<Long> it1 = keys.iterator();
while (keys.size() >= 5) {
Long key = it1.next();
data.remove(idMaps.get(key));
idMaps.remove(key);
it1.remove();
}
}
}
public static void main(String[] args) {
IntentDataHolder.save(12L, Long.valueOf(12));
IntentDataHolder.save(13L, Long.valueOf(13));
IntentDataHolder.save(14L, Long.valueOf(14));
IntentDataHolder.save(15L, Long.valueOf(15));
IntentDataHolder.save(16L, Long.valueOf(16));
IntentDataHolder.save(17L, Long.valueOf(17));
IntentDataHolder.save(18L, Long.valueOf(18));
IntentDataHolder.retrieve(16L);
IntentDataHolder.save(19L, Long.valueOf(19));
IntentDataHolder.retrieve(18L);
}
}
这样的话直接在Activity里调用
Intent intent = new Intent(A.this, B.class);
IntentDataHolder.putExtra(intent, XXX);`
然后在接收的Activity里拿到他就算数据传递成功了
intent = IntentDataHolder.retrieve(getIntent(),XXX);