如何通过Parcelable传递包含View成员的对象数组?
嘿,我看到你在尝试让包含View成员的Variable类实现Parcelable,以此传递它的ArrayList实例。先给你提个醒:直接传递View对象在Android组件间是非常不推荐的,不过先帮你把代码修正到正确的Parcelable实现方式,再给你讲讲为什么不推荐以及更好的替代方案。
先修正你的Parcelable实现代码
你原来用dest.writeValue(mView)的方式不对,因为View本身是实现了Parcelable接口的,应该用专门的Parcelable读写方法:
public class Variable implements Parcelable { public View mView; // 空构造方法,创建实例时需要 public Variable() {} // 从Parcel中解析实例的构造方法 protected Variable(Parcel in) { // 读取Parcelable类型的View,传入View类的类加载器 mView = in.readParcelable(View.class.getClassLoader()); } @Override public int describeContents() { // 没有特殊内容要描述,返回0即可 return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // 写入Parcelable类型的View,而不是用writeValue dest.writeParcelable(mView, flags); } public static final Parcelable.Creator<Variable> CREATOR = new Parcelable.Creator<Variable>() { @Override public Variable createFromParcel(Parcel in) { return new Variable(in); } @Override public Variable[] newArray(int size) { return new Variable[size]; } }; }
为什么不推荐传递View对象?
别着急用上面的代码,先搞清楚风险:
View和当前的Context(比如原Activity)、Window是强绑定的,传递到新的Activity后,它的上下文还是旧的Activity,这很容易引发内存泄漏——旧Activity因为被View引用无法被GC回收。- 跨页面传递的View在新页面里可能无法正常渲染,因为它的布局参数、父容器等都还是旧页面的状态,强行添加到新页面的布局里大概率会出问题。
更合理的替代方案
如果你的需求是传递View的相关信息,完全不需要传递View本身:
- 传递View的ID:如果接收方的布局里有同一个ID的View,直接传递
mView.getId(),在接收方用findViewById重新获取即可。 - 传递View的状态参数:比如你要传递一个TextView,就传递它的文本内容、文字大小、颜色这些可序列化的数据;如果是ImageView,传递图片的Uri或者资源ID,在接收方重新创建View并设置这些参数。
这样既安全又不会有内存泄漏的风险,才是Android组件间传递数据的正确姿势~
内容的提问来源于stack exchange,提问作者KotC
相关产品推荐
相关产品推荐

