好的,我的课程SomeClass
是Parcelable
。
它有一个名为Parcelable
的另一个SuperClass
类的数组。在SomeClass
的构造函数中,我正在尝试将SuperClass
对象的数组读入myArray
实例变量。这很简单;但是:
SuperClass
有两个子类FirstSubClass
和SecondSubClass
。数组temp
应该包含所有3个的混合,但由于某种原因,它只有SuperClass
个对象(if
和else if
语句似乎不执行因为temp
的所有元素都不是子类的实例。
public SomeClass(Parcel in) {
myArray = new SuperClass[100];
// this is probably where the problem is due to the classloader parameter:
Object[] temp = in.readArray(SuperClass.class.getClassLoader());
for(int i = 0; i < myArray.length; i++) {
if(temp[i] instanceof FirstSubClass)
myArray[i] = (FirstSubClass) temp[i];
else if(temp[i] instanceof SecondSubClass)
myArray[i] = (SecondSubClass) temp[i];
else
myArray[i] = (SuperClass) temp[i];
}
}
我想弄清楚的是我如何读取可分配对象数组的元素,使得此对象的子类不会自动转换为超类。
(我想我的问题可能非常混乱,请告诉我,如果我这样做了。)
答案 0 :(得分:6)
我尝试重现您的问题但我无法...我使用writeParcelableArray
和不 writeTypedArray
。以下是我创建的课程:
public class SuperClass implements Parcelable {
public static final Parcelable.Creator<SuperClass> CREATOR = new Creator<SuperClass>() {
@Override
public SuperClass[] newArray(int size) {
return new SuperClass[size];
}
@Override
public SuperClass createFromParcel(Parcel source) {
return new SuperClass(source);
}
};
private String label;
public SuperClass() {
}
protected SuperClass(Parcel source) {
label = source.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(label);
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
}
及其子课程:
public class FirstSubClass extends SuperClass {
public static final Parcelable.Creator<FirstSubClass> CREATOR = new Creator<FirstSubClass>() {
@Override
public FirstSubClass[] newArray(int size) {
return new FirstSubClass[size];
}
@Override
public FirstSubClass createFromParcel(Parcel source) {
return new FirstSubClass(source);
}
};
public FirstSubClass() {
super();
}
public FirstSubClass(Parcel source) {
super(source);
}
}
和
public class SecondSubClass extends SuperClass {
public static final Parcelable.Creator<SecondSubClass> CREATOR = new Creator<SecondSubClass>() {
@Override
public SecondSubClass[] newArray(int size) {
return new SecondSubClass[size];
}
@Override
public SecondSubClass createFromParcel(Parcel source) {
return new SecondSubClass(source);
}
};
public SecondSubClass() {
super();
}
public SecondSubClass(Parcel source) {
super(source);
}
}
和SomeClass
:
public class SomeClass implements Parcelable {
public static final Parcelable.Creator<SomeClass> CREATOR = new Creator<SomeClass>() {
@Override
public SomeClass[] newArray(int size) {
return new SomeClass[size];
}
@Override
public SomeClass createFromParcel(Parcel source) {
return new SomeClass(source);
}
};
private String name;
private SuperClass[] array;
public SomeClass(String name, SuperClass[] array) {
this.name = name;
this.array = array;
}
protected SomeClass(Parcel source) {
this.name = source.readString();
Parcelable[] temp = source.readParcelableArray(SuperClass.class.getClassLoader());
array = new SuperClass[temp.length];
for (int i = 0; i < temp.length; i++) {
array[i] = (SuperClass) temp[i];
}
}
public String toString() {
StringBuilder sb = new StringBuilder(name);
if (array == null || array.length == 0) {
sb.append(" Array is empty");
} else {
sb.append(" Array:");
for (SuperClass sc : array) {
sb.append(sc.getClass().getSimpleName());
sb.append(",");
}
sb.setLength(sb.length() - 1);
}
return sb.toString();
}
public String getName() {
return name;
}
public SuperClass[] getArray() {
return array;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeParcelableArray(array, flags);
}
@Override
public int describeContents() {
return 0;
}
}
从活动中点击一个按钮,创建一个SomeClass
对象,附加到我开始一个新活动的意图,然后从那里记录传递的值。启动活动的功能:
@Override
public void onClick(View v) {
SuperClass[] array = new SuperClass[] { new SuperClass(), new FirstSubClass(), new SecondSubClass(), new SuperClass() };
SomeClass cl = new SomeClass("My Label", array);
Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("PASS", cl);
startActivity(intent);
}
和NextActivity
:
public class NextActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set some content if you wish
Log.d("LOG_TAG", "Passed value: " + getIntent().getParcelableExtra("PASS"));
}
}
我可以在日志中看到:
Passed value: My Label Array:SuperClass,FirstSubClass,SecondSubClass,SuperClass
我之前的活动正是如此...检查与您的代码的差异,我怀疑您没有为CREATOR
和FirstSubClass
撰写SecondSubClass
答案 1 :(得分:-1)
不确定为什么你需要在readArray方法中获取类加载器,但我拍摄了一个代码示例 - 所以整个示例都有几段代码。
示例Parcelable类 - 示例中其他一些的基类
/**
*/
public class Parcelable {
public String parcel() {
return "in Parcelable.parcel()...";
}
}
示例SomeClass - 更改为强制数组匹配从Parcel类返回的硬编码大小。如果数组只包含那些类型,那么你可以只转换为Parcelable而不必转换为FirstSubClass,SecondSubClass和SuperClass。
/**
*/
public class SomeClass extends Parcelable {
private Parcelable[] myArray;
public SomeClass(Parcel in) {
myArray = new SuperClass[3];
// this is probably where the problem is due to the classloader parameter:
//Object[] temp = in.readArray(SuperClass.class.getClassLoader());
Object[] temp = in.readArray();
/*
for(int i = 0; i < 3; i++) {
if(temp[i] instanceof FirstSubClass)
myArray[i] = (FirstSubClass) temp[i];
else if(temp[i] instanceof SecondSubClass)
myArray[i] = (SecondSubClass) temp[i];
else
myArray[i] = (SuperClass) temp[i];
}*/
for(int i = 0; i < 3; i++) {
myArray[i] = (Parcelable) temp[i];
}
}
public String parcel() {
return "In SomeClass.parcel()...";
}
public void show() {
for (Parcelable p : myArray) {
System.out.println (p.parcel());
}
}
public static void main(String[] args ){
SomeClass sc = new SomeClass(new Parcel());
sc.show();
}
}
示例Parcel类 - 由于没有信息而不得不伪造。
/**
*/
public class Parcel {
public Object[] readArray() {
Object[] array = new Object[3];
array[0] = new SuperClass();
array[1] = new FirstSubClass();
array[2] = new SecondSubClass();
return array;
}
}
Sample SuperClass
/**
*/
public class SuperClass extends Parcelable {
public String parcel() {
return "In SuperClass.parcel()...";
}
}
示例FirtSubClass
/**
*/
public class FirstSubClass extends SuperClass {
public String parcel() {
return "In FirstSubClass.parcel()...";
}
}
示例SecondSubClass
/**
*/
public class SecondSubClass extends SuperClass {
public String parcel() {
return "In SecondSubClass.parcel()...";
}
}