如何让基于JSONObject构造的自定义CarListing类实现Parcelable?
解决CarListing实现Parcelable的最佳方案
你的核心问题确实出在用JSONObject作为构造参数上——因为JSONObject本身不支持Parcelable,而且Parcelable的设计是用来序列化纯数据对象,不是用来处理JSON解析这种业务逻辑的。下面是最清晰可靠的解决方案:
步骤1:重构CarListing类,拆分JSON解析与对象构造
把原来在构造函数里的JSON解析逻辑移到HttpGet线程中,让CarListing的构造函数只接收解析后的原始字段参数,这样既符合单一职责原则,也能顺利实现Parcelable。
修改后的CarListing类框架:
public class CarListing implements Parcelable { // 保留所有你的字段:make, model, trim... images等 String make, model, trim, vin, color, condition, transmission, engine, drivetype, seller_type, seller_name, website, city, state; int year, price, mileage, cylinders; double distance; ArrayList<String> images; boolean one_owner, clean_title; int index; public HashMap<String, String> listview_hashmap; // 新的构造函数:接收所有解析后的字段 public CarListing(String make, String model, String trim, String vin, String color, String condition, String transmission, String engine, String drivetype, String seller_type, String seller_name, String website, String city, String state, int year, int price, int mileage, int cylinders, double distance, ArrayList<String> images, boolean one_owner, boolean clean_title, int index) { this.make = make; this.model = model; this.trim = trim; this.vin = vin; this.color = color; this.condition = condition; this.transmission = transmission; this.engine = engine; this.drivetype = drivetype; this.seller_type = seller_type; this.seller_name = seller_name; this.website = website; this.city = city; this.state = state; this.year = year; this.price = price; this.mileage = mileage; this.cylinders = cylinders; this.distance = distance; this.images = images; this.one_owner = one_owner; this.clean_title = clean_title; this.index = index; this.listview_hashmap = new HashMap<>(); } // 保留你的capitalizeLetters、makeHashMap方法 public String capitalizeLetters(String input) { String[] array = input.split(" "); String output = ""; int n = array.length; for(int i=0;i<n;i++) { String cap = array[i].substring(0, 1).toUpperCase() + array[i].substring(1); output += cap + " "; } return output.trim(); } public void makeHashMap() { String vehicle_title = Integer.toString(this.year) + " " + this.make + " " + this.model + " " + this.trim; String vehicle_information = NumberFormat.getIntegerInstance().format(this.mileage) + " miles | " + this.color + " | " + this.condition + " | $" + NumberFormat.getIntegerInstance().format(this.price); String dealer_name = this.seller_name; String location = String.format("%.1f mi.", this.distance) + " | " + this.city + ", " + this.state; String first_img = this.images.isEmpty() ? "" : this.images.get(0); this.listview_hashmap.put("title", vehicle_title); this.listview_hashmap.put("information", vehicle_information); this.listview_hashmap.put("dealer", dealer_name); this.listview_hashmap.put("distance", location); this.listview_hashmap.put("first_image", first_img); } // 接下来实现Parcelable相关方法 }
然后在你的HttpGet线程中,先完成JSON解析,把所有需要的字段提取出来,再调用这个新构造函数创建CarListing对象:
// 在HttpGet任务的解析逻辑中 JSONObject input = ...; // 从API获取的JSON对象 int index = ...; // 解析所有字段(和你原来构造函数里的逻辑一致,只是把结果存到变量里) String vin = input.has("vin") ? input.getString("vin") : "N/A"; int price = input.has("price") ? input.getInt("price") : 1; int mileage = input.has("mileage") ? input.getInt("mileage") : 1; String website = input.has("vdp_url") ? input.getString("vdp_url") : "N/A"; boolean one_owner = input.has("carfax_1_owner") ? input.getBoolean("carfax_1_owner") : true; boolean clean_title = input.has("carfax_clean_title") ? input.getBoolean("carfax_clean_title") : true; String color = input.has("exterior_color") ? input.getString("exterior_color") : "N/A"; String seller_type = input.has("seller_type") ? input.getString("seller_type") : "N/A"; String condition = input.has("inventory_type") ? input.getString("inventory_type") : "N/A"; // 解析build嵌套对象 int year = 1970; String make = "N/A"; String model = "N/A"; String trim = "N/A"; String transmission = "N/A"; String drivetype = "N/A"; int cylinders = 4; String engine = "N/A"; double distance = 0; if(input.has("build")) { JSONObject build = input.getJSONObject("build"); year = build.has("year") ? build.getInt("year") : 1970; make = build.has("make") ? build.getString("make") : "N/A"; model = build.has("model") ? build.getString("model") : "N/A"; trim = build.has("trim") ? build.getString("trim") : "N/A"; transmission = build.has("transmission") ? build.getString("transmission") : "N/A"; drivetype = build.has("drivetrain") ? build.getString("drivetrain") : "N/A"; cylinders = build.has("cylinders") ? build.getInt("cylinders") : 4; engine = build.has("engine") ? build.getString("engine") : "N/A"; distance = build.has("dist") ? build.getDouble("dist") : 0; } // 解析dealer嵌套对象 String seller_name = "N/A"; String city = "N/A"; String state = "N/A"; if(input.has("dealer")) { JSONObject dealer = input.getJSONObject("dealer"); seller_name = dealer.has("name") ? capitalizeLetters(dealer.getString("name")) : "N/A"; city = dealer.has("city") ? dealer.getString("city") : "N/A"; state = dealer.has("state") ? dealer.getString("state") : "N/A"; } // 解析images ArrayList<String> images = new ArrayList<>(); if(input.has("media")) { JSONObject img_json = input.getJSONObject("media"); if(img_json.has("photo_links")) { JSONArray img_array = img_json.getJSONArray("photo_links"); int n = img_array.length(); for(int i=0;i<n;i++) { if(i >= 50) break; images.add(img_array.getString(i)); } } } // 创建CarListing对象并生成HashMap CarListing car = new CarListing(make, model, trim, vin, color, condition, transmission, engine, drivetype, seller_type, seller_name, website, city, state, year, price, mileage, cylinders, distance, images, one_owner, clean_title, index); car.makeHashMap();
步骤2:实现Parcelable接口
现在你的CarListing类只有纯数据字段,很容易实现Parcelable。需要添加两个核心方法:writeToParcel(把字段写入Parcel)和CREATOR(从Parcel恢复对象)。
在CarListing类中添加以下代码:
// Parcelable实现 @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(this.make); dest.writeString(this.model); dest.writeString(this.trim); dest.writeString(this.vin); dest.writeString(this.color); dest.writeString(this.condition); dest.writeString(this.transmission); dest.writeString(this.engine); dest.writeString(this.drivetype); dest.writeString(this.seller_type); dest.writeString(this.seller_name); dest.writeString(this.website); dest.writeString(this.city); dest.writeString(this.state); dest.writeInt(this.year); dest.writeInt(this.price); dest.writeInt(this.mileage); dest.writeInt(this.cylinders); dest.writeDouble(this.distance); dest.writeStringList(this.images); dest.writeByte(this.one_owner ? (byte) 1 : (byte) 0); dest.writeByte(this.clean_title ? (byte) 1 : (byte) 0); dest.writeInt(this.index); } // 从Parcel恢复对象的构造函数 protected CarListing(Parcel in) { this.make = in.readString(); this.model = in.readString(); this.trim = in.readString(); this.vin = in.readString(); this.color = in.readString(); this.condition = in.readString(); this.transmission = in.readString(); this.engine = in.readString(); this.drivetype = in.readString(); this.seller_type = in.readString(); this.seller_name = in.readString(); this.website = in.readString(); this.city = in.readString(); this.state = in.readString(); this.year = in.readInt(); this.price = in.readInt(); this.mileage = in.readInt(); this.cylinders = in.readInt(); this.distance = in.readDouble(); this.images = in.createStringArrayList(); this.one_owner = in.readByte() != 0; this.clean_title = in.readByte() != 0; this.index = in.readInt(); this.listview_hashmap = new HashMap<>(); // 恢复后重新生成HashMap this.makeHashMap(); } public static final Parcelable.Creator<CarListing> CREATOR = new Parcelable.Creator<CarListing>() { @Override public CarListing createFromParcel(Parcel source) { return new CarListing(source); } @Override public CarListing[] newArray(int size) { return new CarListing[size]; } };
步骤3:传递对象到SecondActivity
现在你的CarListing是Parcelable类型了,可以直接通过Intent传递:
在MainActivity中:
// 假设你有一个CarListing对象列表 ArrayList<CarListing> carList = ...; Intent intent = new Intent(MainActivity.this, SecondActivity.class); intent.putParcelableArrayListExtra("CAR_LIST", carList); startActivity(intent);
在SecondActivity中接收:
ArrayList<CarListing> carList = getIntent().getParcelableArrayListExtra("CAR_LIST"); // 拿到列表后,就可以取出每个CarListing的listview_hashmap给适配器用了
为什么这个方案更好?
- 避免了在Parcelable中处理JSON解析的异常逻辑,代码更清晰易维护
- 符合Parcelable的设计初衷:只序列化纯数据,不包含业务逻辑
- 后续添加或删除字段时,只需要修改构造函数和Parcelable相关方法,成本更低
- 不需要序列化HashMap(可以重新生成),减少不必要的复杂度
内容的提问来源于stack exchange,提问作者Darren C.
相关产品推荐
相关产品推荐

