Intent是安卓开发里一个比较常用的对象,最简单的我们可以用它来开启一个activity或service,或者发送一个广播,在同一个进程应用里,Intent可以说是安卓四大组件之间沟通的桥梁。
对于这些熟悉的用法,这里不做赘述,这篇目的主要说下Intent的需要注意的一个地方,那就是对于Intent携带数据的问题。
1. 可以携带哪些数据?
我们都知道Intent可以携带数据,那么究竟可以携带哪些数据呢。
从图上可以看出,Intent可以传递基本的数据类型,以及实现了Serializable和Parcelable接口的数据。
2. 为什么是这些数据类型?
Intent作为数据传输的载体,不止可以实现进程内通信,也可以实现进程间通信,进程间通信的最终都是通过二进制数据进行传输的,那么就要求所携带的数据是可以进行二进制读写的,这点可以参照AIDL的实现方式。
所以对应的数据类型,就只有上面列出的那些,八大基本数据类型以及实现了Serializable和Parcelable接口的数据。
3. Intent携带数据的大小有没有限制?
肯定有限制,但不是以讹传讹的40k,我们可以做个试验,最简单的使用Intent在activity之间传递一个Bitmap。
具体的测试过程就不贴了,直接说结论:Intent对数据的大小是有限制的,超过了会报错,这个数据的大小限制在500kb左右,当然是比40k要大的多的,但是这也不能成为我们用Intent来传递大体积数据的理由,之前在项目中遇到过使用Intent来传递一个接口返回List对象,在测试环境未出现问题,切到线上环境才发现大量奔溃,究其原因是因为测试数据量并没有达到Intent的限制,但线上环境数据量则明显超过500k了,作为一个程序员来说,还是不可以心存侥幸,或者说这样的用法完全是应该禁止的。
4. 如果启动一个activity的时候一定要传递大体积的数据怎么办?
这是一个很多人都遇到过的问题,解决办法也是各式各样,最简单的方式有用Application传递的,有用单例传递的,实现原理都差不多。下面贴出我自己的实现方式。
public class IntentHelper {
private IntentHelper(){}
private static IntentHelper instance; //单例
private Map<String, Object> dataPool = new HashMap<>(); //存放数据
public static IntentHelper getInstance(){
if(instance == null){
synchronized (IntentHelper.class){
if(instance == null)
instance = new IntentHelper();
}
}
return instance;
}
/**
* 暂存要传递的数据
* @param key
* @param data
*/
public void put(String key, Object data){
dataPool.put(key, data);
}
/**
* 获取
* @param key
* @return
*/
public Object get(String key){
return dataPool.get(key);
}
/**
* 传递完成后从map中移除掉
* @param key
*/
public void release(String key){
dataPool.remove(key);
}
}
存储:
Intent intent = new Intent(MainActivity.this, TestWebViewActivity.class);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_deal);
Log.e("Versys","图片的大小是 : "+bitmap.getByteCount()/1024+"kb");
String key = UUID.randomUUID().toString(); //建议key使用uuid
IntentHelper.getInstance().put(key, bitmap);
intent.putExtra("key", key);
startActivity(intent);
获取:
String key = getIntent().getStringExtra("key");
Bitmap bitmap = (Bitmap) IntentHelper.getInstance().get(key);
IntentHelper.getInstance().release(key); //获取到之后从单例的map中移除,防止内存泄漏
总结:
到这里关于Intent数据传递方面的就说的差不多了,希望能给大家在工作中或是面试的时候带来帮助。