It's happening for 0.08% of our users.
One of the crashes happening on Samsung Galaxy S10 running Android 11
不过,在运行 Android 11 的三星 Galaxy S10 上,它并没有崩溃!
有谁知道为什么?
崩溃的地方
Photo[] photoArray = (Photo[]) bundle.getParcelableArray(EXTRA_PHOTOS);
第一个发现
Photo photo1 = new Photo(231, "url", "photoid", "profilid", "caption");
Parcelable[] parcelables1 = new Parcelable[]{photo1};
Photo[] array = (Photo[]) parcelables1;
Throws ClassCastException
这与事实相结合Bundle#getParcelableArray
只返回一个 Parcelable 数组,而不是具体类 Photo 数组解释了为什么会发生崩溃
但为什么只有部分用户会出现这种情况?
第二个发现
这个帖子 https://stackoverflow.com/questions/51714927/pass-array-in-intent-using-parcelable声称getParcelableArray()
不会起作用,只能getParcelableArrayListExtra()
或者单独选角也可以,但我不清楚为什么
第三个发现
所以我了解到向下转型数组不应该在 Java 或 Kotlin 中工作,至少不能像 Android Bundle 那样工作。
之所以getParcelableArrayListExtra()
有效是因为它假定通用类型并确实处理该类型。
问题仍然是:怎么会getParcelableArray()
在我的真实设备和模拟器中运行良好吗?这里是否隐藏着某种黑魔法?
代码如下
照片.java
public class Photo implements Serializable, Model, Parcelable {
private String caption;
private String id, idProfile;
private int position;
private String iphoneFullscreen;
public Photo(int position, String url, String photoId, String profileId, String caption) {
iphoneFullscreen = url;
this.position = position;
this.id = photoId;
idProfile = profileId;
this.caption = caption;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.caption);
dest.writeString(this.id);
dest.writeString(this.idProfile);
dest.writeInt(this.position);
dest.writeString(this.iphoneFullscreen);
}
protected Photo(Parcel in) {
this.caption = in.readString();
this.id = in.readString();
this.idProfile = in.readString();
this.position = in.readInt();
this.iphoneFullscreen = in.readString();
}
public static final Parcelable.Creator<Photo> CREATOR = new Parcelable.Creator<Photo>() {
@Override
public Photo createFromParcel(Parcel source) {
return new Photo(source);
}
@Override
public Photo[] newArray(int size) {
return new Photo[size];
}
};
}
它是如何提供和消费的
DialogFragmentPhotoGallery.java
public static DialogFragment newInstance(
Photo[] photos) {
DialogFragmentPhotoGallery dialogFragmentPhotoGallery = new DialogFragmentPhotoGallery();
Bundle args = new Bundle();
args.putParcelableArray(DialogFragmentPhotoGallery.EXTRA_PHOTOS, photos);
dialogFragmentPhotoGallery.setArguments(args);
return dialogFragmentPhotoGallery;
}
public View onCreateView(
@NonNull LayoutInflater inflater,
ViewGroup parent,
Bundle savedInstanceState) {
if (getArguments() != null) {
Photo[] photos = (Photo[]) getArguments().getParcelableArray(EXTRA_PHOTOS); // <-- CRASH
// do things with photos
}