Protobuf Java对象转Serializable/Parcelable及Android存储方案问询
把Protobuf Java对象存入Android Bundle的几种方案
嘿,这个场景我之前在Android项目里刚好碰到过,给你几个实用的方案,按推荐程度排序:
方案1:直接转字节数组(最推荐)
其实根本不用额外转成Serializable或Parcelable,因为Android的Bundle本身就支持存储byte[],而Protobuf对象自带序列化/反序列化方法,这是最省事且高效的方式:
存入Bundle
// 假设你的Protobuf对象是MyProtoMessage类型的protoObj byte[] protoBytes = protoObj.toByteArray(); bundle.putByteArray("my_proto_key", protoBytes);
从Bundle还原
byte[] protoBytes = bundle.getByteArray("my_proto_key"); if (protoBytes != null) { MyProtoMessage restoredProto = MyProtoMessage.parseFrom(protoBytes); // 这里就拿到还原后的对象啦 }
为什么推荐这个? 因为Protobuf的toByteArray()本身就是高效的二进制序列化,比Java原生的Serializable性能好太多,而且不需要写额外的包装类代码,直接用就行。
方案2:包装成Serializable对象(如果必须用Serializable类型)
如果你的业务场景要求必须用Serializable(比如某些老代码依赖),可以写一个简单的包装类,把Protobuf的字节数组包进去:
import java.io.Serializable; import com.google.protobuf.InvalidProtocolBufferException; public class ProtoSerializableWrapper implements Serializable { private final byte[] protoBytes; public ProtoSerializableWrapper(MyProtoMessage proto) { this.protoBytes = proto.toByteArray(); } public MyProtoMessage getProto() throws InvalidProtocolBufferException { return MyProtoMessage.parseFrom(protoBytes); } }
使用方式
// 存入 bundle.putSerializable("proto_serializable", new ProtoSerializableWrapper(protoObj)); // 还原 ProtoSerializableWrapper wrapper = (ProtoSerializableWrapper) bundle.getSerializable("proto_serializable"); if (wrapper != null) { try { MyProtoMessage restoredProto = wrapper.getProto(); } catch (InvalidProtocolBufferException e) { // 处理解析异常 e.printStackTrace(); } }
方案3:包装成Parcelable对象(适合跨进程传递)
如果需要跨进程传递(比如用Intent传对象),Parcelable比Serializable性能更好,同样可以写一个包装类实现Parcelable接口:
import android.os.Parcel; import android.os.Parcelable; import com.google.protobuf.InvalidProtocolBufferException; public class ProtoParcelableWrapper implements Parcelable { private final byte[] protoBytes; public ProtoParcelableWrapper(MyProtoMessage proto) { this.protoBytes = proto.toByteArray(); } protected ProtoParcelableWrapper(Parcel in) { protoBytes = in.createByteArray(); } public static final Creator<ProtoParcelableWrapper> CREATOR = new Creator<ProtoParcelableWrapper>() { @Override public ProtoParcelableWrapper createFromParcel(Parcel in) { return new ProtoParcelableWrapper(in); } @Override public ProtoParcelableWrapper[] newArray(int size) { return new ProtoParcelableWrapper[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeByteArray(protoBytes); } public MyProtoMessage getProto() throws InvalidProtocolBufferException { return MyProtoMessage.parseFrom(protoBytes); } }
使用方式
// 存入Bundle/Intent bundle.putParcelable("proto_parcelable", new ProtoParcelableWrapper(protoObj)); // 还原 ProtoParcelableWrapper wrapper = bundle.getParcelable("proto_parcelable"); if (wrapper != null) { try { MyProtoMessage restoredProto = wrapper.getProto(); } catch (InvalidProtocolBufferException e) { e.printStackTrace(); } }
总结一下:优先用方案1,简单高效;如果有特殊类型要求,再考虑方案2或3。
内容的提问来源于stack exchange,提问作者alizeyn
相关产品推荐
相关产品推荐

