抽象和派生中 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 没有通过构造函数