Android序列化遇到的问题

 一,问题提出
 最近在开发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中提供的接口。
 

你可能感兴趣的:(Android基础,android,物流,json)