一,问题提出
最近在开发App时使用了Parcelable接口实现序列化,主要是为了能够实现在不同的场景传值,并且传递的是自定义的构造类型,还包含ArraList数据的传递,遇到的问题如下:
//这是我要从网络获取的物流查询信息(JSON格式)
{
"EBusinessID": "1270755",
"ShipperCode": "ANE",
"Success": true,
"LogisticCode": "210001633605",
"State": "2",
"Traces": [
{
"AcceptTime": "2016-04-01 13:44:12",
"AcceptStation": "【和平滨江道】的【和平滨江道】正在派件",
"Remark": ""
},
{
"AcceptTime": "2016-04-01 15:14:31",
"AcceptStation": "",
"Remark": ""
},
{
"AcceptTime": "2016-04-03 09:42:48",
"AcceptStation": "【和平滨江道】的【和平滨江道】正在派件",
"Remark": ""
}
]
}
//格式化后创建的JavaBean类
public class ExpressInfo implements Parcelable {
private String State;//物流状态 2-在途中,3-签收,4-问题件
private transient ArrayList Traces;//物流信息记录,不对内部的数据进行传值,单独传值
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(State);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator CREATOR = new Creator() {
@Override
public ExpressInfo createFromParcel(Parcel in) {
ExpressInfo info = new ExpressInfo();
info.State = in.readString();
return info;
}
@Override
public ExpressInfo[] newArray(int size) {
return new ExpressInfo[size];
}
};
public String getState() {
return State;
}
public void setState(String State) {
this.State = State;
}
public ArrayList getTraces() {
return Traces;
}
public void setTraces(ArrayList Traces) {
this.Traces = Traces;
}
public static class TracesBean implements Parcelable {
private String AcceptTime;
private String AcceptStation;
private String Remark;
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(AcceptTime);
dest.writeString(AcceptStation);
dest.writeString(Remark);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator CREATOR = new Creator() {
@Override
public TracesBean createFromParcel(Parcel in) {
//return new TracesBean(in);
TracesBean tb = new TracesBean();
tb.AcceptTime = in.readString();
tb.AcceptStation = in.readString();
tb.Remark = in.readString();
return tb;
}
@Override
public TracesBean[] newArray(int size) {
return new TracesBean[size];
}
};
public String getAcceptTime() {
return AcceptTime;
}
public void setAcceptTime(String AcceptTime) {
this.AcceptTime = AcceptTime;
}
public String getAcceptStation() {
return AcceptStation;
}
public void setAcceptStation(String AcceptStation) {
this.AcceptStation = AcceptStation;
}
public String getRemark() {
return Remark;
}
public void setRemark(String Remark) {
this.Remark = Remark;
}
}
@Override
public String toString() {
return "State:" + State + "Traces:" + Traces;
}
}
观察上述代码可以发现,这个类的结构中,类成员不仅包含基本数据类型,还包含集合ArrayList,如果直接将要传递的类进行序列化再传值,编译运行程序就会出现无法传递ArrayList类型数据的提示,解决方式:
(1)ArrayList中的类型参数也必须实现Parcelable接口,同时实现其方法;
(2)将ExpressInfo类型的内部类加上transient修饰:
private transient ArrayList Traces;
(3)传递数据方法:方法是将类分开传递,将外部类和内部类分割为两部分进行传递,然后获取的时候也分开进行获取。
result = KdniaoTrackQueryAPI.getOrderTracesByJson(expCode, expNum.getText().toString());
ExpressInfo info = parse2ExpressInfo(result);
ArrayList.TracesBean> tbList = info.getTraces();
if (tbList == null) {
Log.d(TAG, "run: tbList == null");
}
//将物流信息发送到物流详情的页面中
Intent intent = new Intent(ExpressMainActivity.this, ExpressInfoActivity.class);
//intent.putExtra("info", info);
Bundle bundle = new Bundle();
bundle.putParcelable("info", info);
bundle.putParcelableArrayList("info_list", tbList);
intent.putExtras(bundle);
startActivity(intent);
finish();
/**
* 解析物流信息
* 已经查询成功的情况下进行解析
*
* @return
*/
private ExpressInfo parse2ExpressInfo(String jsonData) {
//物流状态
final String STATE_2 = "在途中";
final String STATE_3 = "签收";
final String STATE_4 = "问题件";
//物流实例
ExpressInfo expressInfo = new ExpressInfo();
try {
JSONObject rootObject = new JSONObject(jsonData);
//物流状态:2-在途中,3-签收,4-问题件
if (rootObject.getBoolean("Success")) {//判断是否获取成功
String s = rootObject.getString("State");//物流状态
String state = "";
//判断物流状态
switch (s) {
case "2":
state = STATE_2;
break;
case "3":
state = STATE_3;
break;
case "4":
state = STATE_4;
break;
default:
break;
}
expressInfo.setState(state);
JSONObject obj = null;
//状态列表
ArrayList TbList = new ArrayList<>();
//单条记录
ExpressInfo.TracesBean tb = null;
//获取物流信息列表
JSONArray traceArray = rootObject.getJSONArray("Traces");
for (int i = 0, n = traceArray.length(); i < n; i++) {
//依次获取每一个元素的值
obj = traceArray.getJSONObject(i);
tb = new ExpressInfo.TracesBean();
tb.setAcceptTime(obj.getString("AcceptTime"));
Log.d(TAG, "parse2ExpressInfo: " + obj.getString("AcceptTime"));
tb.setAcceptStation(obj.getString("AcceptStation"));
Log.d(TAG, "parse2ExpressInfo: " + obj.getString("AcceptStation"));
// tb.setRemark(obj.getString("Remark"));
// Log.d(TAG, "parse2ExpressInfo: " + obj.getString("Remark"));
TbList.add(tb);
}
// Log.d(TAG, "parse2ExpressInfo: " + TbList.size());
expressInfo.setTraces(TbList);
} else {
Log.d(TAG, "get ExpressInfo: --->" + rootObject.getBoolean("Success"));
}
} catch (JSONException e) {
e.printStackTrace();
}
return expressInfo;
}
//获取序列化数据的代码块
Intent intent = getIntent();
Bundle b = intent.getExtras();//获取Bundle对象
expressInfo = b.getParcelable("info");
tbList = b.getParcelableArrayList("info_list");
expressState = expressInfo.getState();
Log.d("ExpressInfoActivity", "onCreate: " + expressInfo.getState());
Log.d("ExpressInfoActivity", "onCreate: " + tbList.size());
for (int i = 0, n = tbList.size(); i < n; i++) {
Log.d("ExpressInfoActivity", "onCreate: " + tbList.get(i).getAcceptTime());
Log.d("ExpressInfoActivity", "onCreate: " + tbList.get(i).getAcceptStation());
}
实现序列化的方法有两种:
(1)实现Serializable接口;
(2)实现Parcelable接口;
序列化在开发中是经常使用的工具,Serializable是Java中提供的接口,而Parcelable是Android中提供的接口。