Android Parcelable Understanding - parcelling无效

时间:2014-07-27 11:48:16

标签: android parcelable parcel

所以我想我今天会试用Android中的Parcelling,很快就嘲笑了这个:

public class Unit implements Parcelable {
    private String unitName;
    private int view;
    private Double value;

    /**
     * Constructor
     */
    public Unit() { }

    /**
     * Constructor
     * @param unitName
     */
    public Unit(String unitName) {
        this.unitName = unitName;
    }

    /**
     * Constructor
     * @param unitName
     * @param view
     */
    public Unit(String unitName, int view, Double value) {
        this.unitName = unitName;
        this.view = view;
        this.value = value;
    }

    /**
     * Set the name of the unit of measurement
     * @param name
     */
    public void setUnitName(String name) {
        this.unitName = name;
    }

    /**
     * Set whether the unit of measurement is viewable
     * @param view
     */
    public void setView(int view) {
        this.view = view;
    }

    /**
     * Set the value of the unit
     * @param value
     */
    public void setValue(Double value) { this.value = value; }

    /**
     * Return the unit name
     * @return unitName
     */
    public String getUnitName() {
        return unitName;
    }

    /**
     * Return whether the unit is viewable
     * @return view
     */
    public int getView() {
        return view;
    }

    /**
     * Return the value of this unit
     * @return value
     */
    public Double getValue() { return value; }

    /**
     * Methods for parcelling here
     */

    /**
     * Constructor for parcelling
     * @param in
     */
    public Unit(Parcel in) {
        //
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(new ArrayList<Unit>() {
            //huh?
        });
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Unit createFromParcel(Parcel in) {
            return new Unit(in);
        }

        public Unit[] newArray(int size) {
            return new Unit[size];
        }
    };
}

您可能会注意到我从Parcelable接口覆盖的方法的实现不完整。但是继承,这个类只是一个可以被另一个类别包含的对象。

现在这是我的主要活动:

public class MyActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button send = (Button) findViewById(R.id.sendParcel);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ArrayList<Unit> units = getUnits();
                Intent i = new Intent(getApplicationContext(), UnitListActivity.class);
                i.putParcelableArrayListExtra("units", units);
                startActivity(i);
            }
        });
    }

    /**
     * Return an arraylist of units
     * @return units
     */
    public ArrayList<Unit> getUnits() {
        ArrayList<Unit> units = new ArrayList<Unit>();
        units.add(new Unit("acceleration", 1, 56.45));
        units.add(new Unit("kilograms", 0, 5830.54345));
        units.add(new Unit("metres", 1, 543.54));
        units.add(new Unit("kilometres", 1, 32.43));
        units.add(new Unit("grams", 1, 453.654));
        units.add(new Unit("kilograms", 0, 8.5));
        units.add(new Unit("litres", 1, 344.3));
        units.add(new Unit("millilitres", 0, 4543.879));
        units.add(new Unit("decimeter", 1, 5084903.564567));
        return units;
    }
}

基本上按下按钮会创建Intent,并尝试使用实现ArrayList接口的Object包裹Parcelable。它试图传递给它的类是ListActivity代码,其代码在这里:

public class UnitListActivity extends ListActivity {

    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        UnitListAdapter mTypeAdapter = new UnitListAdapter(getApplicationContext(), bundle.getParcelableArrayList("units"));
        setListAdapter(mTypeAdapter);
    }
}

我在这里为ListActivity创建了这个适配器:

public class UnitListAdapter extends ArrayAdapter<Unit> {

    private ArrayList<Unit> unitsList;
    private Context context;

    public UnitListAdapter(Context c, ArrayList<Unit> units) {
        super(c, R.layout.unit_values, units);
        this.context = c;
        this.unitsList = units;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parentView) {
        View view = null;
        LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflator.inflate(R.layout.unit_values, null);
        TextView textView = (TextView) view.findViewById(R.id.unit_name);
        CheckBox checkBox = (CheckBox) view.findViewById(R.id.check);

        //check box set on check changed listener if I get this far for later

        if(unitsList.get(position).getView() == 1) {
            textView.setText(unitsList.get(position).getUnitName());
            checkBox.setChecked(true);
        } else {
            textView.setText(unitsList.get(position).getUnitName());
        }

        return view;
    }

}

现在我不明白为什么在ListActivity这一行: UnitListAdapter mTypeAdapter = new UnitListAdapter(getApplicationContext(), bundle.getParcelableArrayList("units"));抱怨不是获取Unit对象,而是获取Parcelable个对象,因为类Unit实现了它们。

这是否意味着在我的适配器中我必须更改列表以期望Parcelable对象,如果,这意味着它将改变我读取它们的方式?

我也不理解writeToParcel,文档说它会使对象变平,所以我想,因为我想要展平列表,我需要writeList方法,但之后呢?看起来它正在展平Unit对象而不是列表。

这也让我问起构造函数:

public Unit(Parcel in) {
        //
}

我猜我需要做这样的事情:

readTypedList() - 我不明白为什么我必须这样做,因为我将创建包裹。所以我不确定如何实现这个东西...我真的想深入了解parcelling是如何工作的,我没有找到有用的文档以及如何在这个例子中成功地工作。非常感谢帮助和建议。

2 个答案:

答案 0 :(得分:0)

我认为您需要明确告诉Parcelable Creator需要创建哪种类型,因此请尝试将代码更改为:

public static final Parcelable.Creator<Unit> CREATOR = new Parcelable.Creator<Unit>() {
    public Unit createFromParcel(Parcel in) {
        return new Unit(in);
    }

    public Unit[] newArray(int size) {
        return new Unit[size];
    }
};

答案 1 :(得分:0)

public static final Parcelable.Creator<Unit> CREATOR = new Parcelable.Creator<Unit>() {
    public Unit createFromParcel(Parcel in) {
        Unit u = new Unit();
        u.setUnitName(in.readString());
        //...
        //populate all atributes
        return u;
    }

    public Unit[] newArray(int size) {
        return new Unit[size];
    }
};
相关问题