抽象和派生中 Parcelable 中的构造函数问题 类
Problem with Constructor in Parcelable in both Abstract and Derived Classes
我有一个抽象 class 及其子项,我想通过一个 activity 将子项传递给另一个 intent.putExtra(String, Parcelable);
接收 Intent 的 activity 会接受任何 parcelable,因为它是一个扩展抽象 class 的对象。
我在摘要 class 和子项中实现了 Parcelable:
public abstract class MyAbstractClass implements Parcelable{
private double dField;
private Integer stringResource;
private MyEnum objEnumType;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
//TODO Age
parcel.writeDouble(dField); parcel.writeString(this.objEnumType.toString());
parcel.writeInt(stringResource);
}
public static final Parcelable.Creator<MyAbstractClass> CREATOR = new Creator<MyAbstractClass>() {
@Override
public MyAbstractClass createFromParcel(Parcel parcel) {
return null;
}
@Override
public MyAbstractClass[] newArray(int i) {
return new MyAbstractClass[0];
}
};
protected MyAbstractClass(Parcel in){
dField = in.readDouble();
this.objEnumType = MyEnum.valueOf(in.readString());
stringResource = in.readInt();
}
}
中子class:
public class MyChildClass extends MyAbstractClass{
public int describeContents(){
return 0;
}
public void writeToParcel(Parcel out, int flags){
super.writeToParcel(out,flags);
}
public static final Parcelable.Creator<MyChildClass> CREATOR = new Creator<MyChildClass>() {
@Override
public MyChildClass createFromParcel(Parcel parcel) {
return null;
}
@Override
public MyChildClass[] newArray(int i) {
return new MyChildClass[0];
}
};
protected MyChildClass(Parcel in) {
super(in);
}
}
在我传递 parcelable 的 FirstActivity 中,我写道,但我收到与 MyChildClass 的构造函数相关的错误:
MyChildClass objChildClass = new MyChildClass(); //I got an error here, expecting a Parcel object?!
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("extraParcelable",objChildClass);
startActivity(intent);
根据 Android Studio 的说法,MyChildClass 需要一个 Parcel 参数给 MyChildClass,但是如果我想通过 Intent 发送这个 class 如何传递一个 Parcel?
编辑
我在 MyChildClass 和 MyAbstractClass 中添加了一个空构造函数:
MyChildClass(){super()}
并且在 MyAbstractClass 中:
MyAbstractClass(){}
在我添加的FirstActivity中:
objChildClass.setDField = 2.5;
objChildClass.setObjEnumType = MyEnum.Type1;
objChildClass.setStringResource = getString(R.string.app_name);
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("extraParcelable",objChildClass);
startActivity(intent);
在第二个活动中:
class SecondActivity : AppCompatActivity() {
private val lbResult by lazy {findViewById<TextView>(R.id.lb_result)}
private val objReceived by lazy {intent?.extras?.getParcelable<MyAbstractClass>("extraParcelable")}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//
//...
//
lbResult.text = objReceived?.dField.toString() //I get a null here
}
}
我在 lbResults 中得到一个空值。当我使用 intent.putExtras(String, Double) 时,代码运行良好,但如果我使用空构造函数,现在使用 parcelable 为 null。否则我会收到想要将 Parcel 作为构造函数传递的错误,(正如我上面写的)
在 MyChildClass 和 MyAbstractClass 中创建一个空构造函数
protected
构造函数将用于在接收端读取包裹。
您还需要一些 public 构造函数 - 当然很可能带有参数 - 来初始化您的对象,以便您可以首先将数据打包。
我在实现 Parcelable 时遇到的问题是由于我在处理 Parcelable 时忽略了有关构造函数的简单错误:
- 首先,如果实现 Parcelable 的 class 没有构造函数,它必须为 class Parcelable 创建一个构造函数以及接收 Parcel 的构造函数。否则,Android Studio 或编译器会抱怨 Parcel 未作为参数提供(因为 class 中唯一的构造函数需要 Parcel 对象)。
public MyChildClass(Parcel parcel){
super(parcel);
}
public MyChildClass(){super();}
我还必须匹配超级 class:
上的构造函数
protected MyAbstractClass(Parcel in){
dField = in.readDouble();
this.objEnumType = MyEnum.valueOf(in.readString());
stringResource = in.readInt();
}
protected MyAbstractClass(){}
- 其次,接收Parcel对象的构造函数必须在
Parcelabe.Creator CREATOR
内的createFromParcel
方法中调用。这是我的第二个错误。 Android 工作室自动生成 Parcelable.Creator
仅将 return null
放入此方法中。
public static final Parcelable.Creator<MyChildClass> CREATOR = new Creator<MyChildClass>() {
@Override
public MyChildClass createFromParcel(Parcel parcel) {
return new MyChildClass(parcel); //It needs to replace the default `return null` by the instance of the class calling the constructor to pass the Parcel object
}
@Override
public MyChildClass[] newArray(int i) {
return new MyChildClass[0];
}
};
- 第三:由于
Parcelable.Creator CREATOR
中的方法 public T createFromParcel
需要 class 的实例,我从 MyAbstractClass 中删除了 Parcelable.Creator CREATOR
,因为它是一个抽象 class 我无法在那里创建任何实例
现在我可以通过活动传递我派生的 classes 而没有 null 或抱怨 Parcel 没有通过构造函数
我有一个抽象 class 及其子项,我想通过一个 activity 将子项传递给另一个 intent.putExtra(String, Parcelable);
接收 Intent 的 activity 会接受任何 parcelable,因为它是一个扩展抽象 class 的对象。
我在摘要 class 和子项中实现了 Parcelable:
public abstract class MyAbstractClass implements Parcelable{
private double dField;
private Integer stringResource;
private MyEnum objEnumType;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
//TODO Age
parcel.writeDouble(dField); parcel.writeString(this.objEnumType.toString());
parcel.writeInt(stringResource);
}
public static final Parcelable.Creator<MyAbstractClass> CREATOR = new Creator<MyAbstractClass>() {
@Override
public MyAbstractClass createFromParcel(Parcel parcel) {
return null;
}
@Override
public MyAbstractClass[] newArray(int i) {
return new MyAbstractClass[0];
}
};
protected MyAbstractClass(Parcel in){
dField = in.readDouble();
this.objEnumType = MyEnum.valueOf(in.readString());
stringResource = in.readInt();
}
}
中子class:
public class MyChildClass extends MyAbstractClass{
public int describeContents(){
return 0;
}
public void writeToParcel(Parcel out, int flags){
super.writeToParcel(out,flags);
}
public static final Parcelable.Creator<MyChildClass> CREATOR = new Creator<MyChildClass>() {
@Override
public MyChildClass createFromParcel(Parcel parcel) {
return null;
}
@Override
public MyChildClass[] newArray(int i) {
return new MyChildClass[0];
}
};
protected MyChildClass(Parcel in) {
super(in);
}
}
在我传递 parcelable 的 FirstActivity 中,我写道,但我收到与 MyChildClass 的构造函数相关的错误:
MyChildClass objChildClass = new MyChildClass(); //I got an error here, expecting a Parcel object?!
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("extraParcelable",objChildClass);
startActivity(intent);
根据 Android Studio 的说法,MyChildClass 需要一个 Parcel 参数给 MyChildClass,但是如果我想通过 Intent 发送这个 class 如何传递一个 Parcel?
编辑
我在 MyChildClass 和 MyAbstractClass 中添加了一个空构造函数:
MyChildClass(){super()}
并且在 MyAbstractClass 中:
MyAbstractClass(){}
在我添加的FirstActivity中:
objChildClass.setDField = 2.5;
objChildClass.setObjEnumType = MyEnum.Type1;
objChildClass.setStringResource = getString(R.string.app_name);
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("extraParcelable",objChildClass);
startActivity(intent);
在第二个活动中:
class SecondActivity : AppCompatActivity() {
private val lbResult by lazy {findViewById<TextView>(R.id.lb_result)}
private val objReceived by lazy {intent?.extras?.getParcelable<MyAbstractClass>("extraParcelable")}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//
//...
//
lbResult.text = objReceived?.dField.toString() //I get a null here
}
}
我在 lbResults 中得到一个空值。当我使用 intent.putExtras(String, Double) 时,代码运行良好,但如果我使用空构造函数,现在使用 parcelable 为 null。否则我会收到想要将 Parcel 作为构造函数传递的错误,(正如我上面写的)
在 MyChildClass 和 MyAbstractClass 中创建一个空构造函数
protected
构造函数将用于在接收端读取包裹。
您还需要一些 public 构造函数 - 当然很可能带有参数 - 来初始化您的对象,以便您可以首先将数据打包。
我在实现 Parcelable 时遇到的问题是由于我在处理 Parcelable 时忽略了有关构造函数的简单错误:
- 首先,如果实现 Parcelable 的 class 没有构造函数,它必须为 class Parcelable 创建一个构造函数以及接收 Parcel 的构造函数。否则,Android Studio 或编译器会抱怨 Parcel 未作为参数提供(因为 class 中唯一的构造函数需要 Parcel 对象)。
public MyChildClass(Parcel parcel){
super(parcel);
}
public MyChildClass(){super();}
我还必须匹配超级 class:
上的构造函数protected MyAbstractClass(Parcel in){
dField = in.readDouble();
this.objEnumType = MyEnum.valueOf(in.readString());
stringResource = in.readInt();
}
protected MyAbstractClass(){}
- 其次,接收Parcel对象的构造函数必须在
Parcelabe.Creator CREATOR
内的createFromParcel
方法中调用。这是我的第二个错误。 Android 工作室自动生成Parcelable.Creator
仅将return null
放入此方法中。
public static final Parcelable.Creator<MyChildClass> CREATOR = new Creator<MyChildClass>() {
@Override
public MyChildClass createFromParcel(Parcel parcel) {
return new MyChildClass(parcel); //It needs to replace the default `return null` by the instance of the class calling the constructor to pass the Parcel object
}
@Override
public MyChildClass[] newArray(int i) {
return new MyChildClass[0];
}
};
- 第三:由于
Parcelable.Creator CREATOR
中的方法public T createFromParcel
需要 class 的实例,我从 MyAbstractClass 中删除了Parcelable.Creator CREATOR
,因为它是一个抽象 class 我无法在那里创建任何实例
现在我可以通过活动传递我派生的 classes 而没有 null 或抱怨 Parcel 没有通过构造函数