Android,如何在 Parcelable 类中正确使用 readTypedList 方法?

Posted

技术标签:

【中文标题】Android,如何在 Parcelable 类中正确使用 readTypedList 方法?【英文标题】:Android, How to use readTypedList method correctly in a Parcelable class? 【发布时间】:2011-10-10 02:51:37 【问题描述】:

我有两个活动,在第一个活动中,我实例化了一个 Object myObject 的 ArrayList。在第二个活动中,我需要得到这个 Arraylist。我找到了一个教程:http://prasanta-paul.blogspot.com/2010/06/android-parcelable-example.html 我已经实现了我的课程,喜欢它的解释。

公共类 Chapitre 实现 Parcelable

private int numero;
private String titre;
private String description;
private int nbVideo;
private ArrayList<Video> listeVideo;

public Chapitre(int numero, String titre, String description,
        ArrayList<Video> listeVideo) 
    this.numero = numero;
    this.titre = titre;
    this.description = description;
    this.listeVideo = listeVideo;
    this.nbVideo = listeVideo.size();


//Getters and Setters ...

private Chapitre(Parcel source) 
    numero = source.readInt();
    titre = source.readString();
    description = source.readString();
    nbVideo = source.readInt();
    source.readTypedList(listeVideo, Video.CREATOR);


@Override
public int describeContents() 
    return 0;


@Override
public void writeToParcel(Parcel dest, int flags) 
    dest.writeInt(numero);
    dest.writeString(titre);
    dest.writeString(description);
    dest.writeInt(nbVideo);
    dest.writeTypedList(listeVideo);


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

    public Chapitre[] newArray(int size) 
        return new Chapitre[size];
    
;

public 类 Video 实现 Parcelable

private String titre;
private int numero;
private String url;
private String description;
private String imageUrl;
private Bitmap image;
private String duree;

/**
 * 
 * @param nom
 * @param numero
 * @param url
 * @param description
 */
public Video(String titre, String url, String description) 
    super();
    this.titre = titre;
    this.url = url;
    this.description = description;


public Video(int numero, String titre, String url, String description) 
    super();
    this.titre = titre;
    this.url = url;
    this.description = description;
    this.numero = numero;


public Video(String titre,int numero, String url, String description, String imageUrl) 
    super();
    this.titre = titre;
    this.url = url;
    this.description = description;
    this.imageUrl = imageUrl;
    this.numero = numero;

    setImage(fetchImage(imageUrl));



//Getters and Setters ...

@Override
public int describeContents() 
    // TODO Auto-generated method stub
    return 0;


@Override
public void writeToParcel(Parcel dest, int flags) 
    dest.writeString(titre);
    dest.writeInt(numero);
    dest.writeString(url);
    dest.writeString(description);
    dest.writeString(imageUrl);
    dest.writeString(duree);




public Video(Parcel source)
    /*
     * Reconstruct from the Parcel
     */
    Log.v("TAG", "ParcelData(Parcel source): time to put back parcel data");
    titre = source.readString();
    numero = source.readInt();
    url = source.readString();
    description = source.readString();
    imageUrl = source.readString();
    duree = source.readString();


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

    public Video[] newArray(int size) 
        return new Video[size];
    
;

但我在“source.readTypedList(listeVideo, Video.CREATOR);”这一行得到了 nullPointException在课堂上。

07-21 10:07:28.212: ERROR/AndroidRuntime(682): FATAL EXCEPTION: main
07-21 10:07:28.212: ERROR/AndroidRuntime(682): java.lang.RuntimeException: Unable to start activity ComponentInfocom.genicorp.video.proto/com.genicorp.video.proto.Lecture:     java.lang.NullPointerException
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1736)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1752)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.app.ActivityThread.access$1500(ActivityThread.java:123)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:993)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Looper.loop(Looper.java:126)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.app.ActivityThread.main(ActivityThread.java:3997)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at java.lang.reflect.Method.invokeNative(Native Method)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at java.lang.reflect.Method.invoke(Method.java:491)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at dalvik.system.NativeStart.main(Native Method)
07-21 10:07:28.212: ERROR/AndroidRuntime(682): Caused by: java.lang.NullPointerException
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Parcel.readTypedList(Parcel.java:1630)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at com.genicorp.video.proto.Chapitre.<init>(Chapitre.java:70)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at com.genicorp.video.proto.Chapitre.<init>(Chapitre.java:65)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at com.genicorp.video.proto.Chapitre$1.createFromParcel(Chapitre.java:89)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at com.genicorp.video.proto.Chapitre$1.createFromParcel(Chapitre.java:1)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Parcel.readParcelable(Parcel.java:1981)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Parcel.readValue(Parcel.java:1846)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Parcel.readListInternal(Parcel.java:2092)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Parcel.readArrayList(Parcel.java:1536)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Parcel.readValue(Parcel.java:1867)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Parcel.readMapInternal(Parcel.java:2083)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Bundle.unparcel(Bundle.java:215)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.os.Bundle.getParcelableArrayList(Bundle.java:1151)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.content.Intent.getParcelableArrayListExtra(Intent.java:3634)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at com.genicorp.video.proto.Lecture.onCreate(Lecture.java:37)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1700)
07-21 10:07:28.212: ERROR/AndroidRuntime(682):     ... 11 more

我已经为此浪费了 1 天的时间,所以如果有人可以帮助我,那就太好了,

提前致谢

【问题讨论】:

不确定它是否重要,但有些公司会因为看到太多信息而皱眉。从这个未清理的输出中,人们可以根据你的其他问题推断出你为谁工作,以及你正在制作什么样的应用程序。清理你的输出也可以帮助你发现你的错误。 【参考方案1】:

希望您现在已经弄清楚了。但是对于任何偶然发现这个的人。您得到的 NullPointerException 是由从未初始化的 ArrayList 引起的。

这会解决它:

private Chapitre()
    listVideo = new ArrayList<Video>();


private Chapitre(Parcel source) 
    // Call the above constructor
    this();

    numero = source.readInt();
    titre = source.readString();
    description = source.readString();
    nbVideo = source.readInt();
    source.readTypedList(listeVideo, Video.CREATOR);

【讨论】:

完美回应。先生,您应该得到一个“验证”的答案! 这是对上述问题的完美解决方案。 还要注意parcelabler.com 是一个很棒的网站,它会自动为您创建包裹!另请查看***.com/questions/7042272/… 和***.com/questions/24909331/… 了解更多信息。【参考方案2】:

另一种解决方案:使用createTypedArrayList 而不是readTypedList,这需要非空 List 对象引用

【讨论】:

【参考方案3】:

另外请记住,您必须以相同的顺序读取和写入 parcelable 对象属性! 我也是 2 小时,因为解组与编组的顺序不同。

【讨论】:

【参考方案4】:

还可以考虑使用不可变的空列表初始化对象。

private ArrayList&lt;Video&gt; listevideo = Collections.emptyList()

更多详情:Collections.emptyList() vs. new instance

【讨论】:

由于readTypedList() 填充了您提供的列表,因此提供来自Collections.emptyList() 的不可变列表将导致抛出UnsupportedOperationException 对不起,我应该澄清一下 - 初始化以表明任何想要使用该列表的人都必须创建一个新的合同

以上是关于Android,如何在 Parcelable 类中正确使用 readTypedList 方法?的主要内容,如果未能解决你的问题,请参考以下文章

Android studio自动生成Parcelable 接口方法的代码

从 Parcelable 类中读取和写入 java.util.Date

android 怎么将一个类中的arraylist<bitmap>序列化。

如何使用 ArrayList<Parcelable> 正确实现 Parcelable?

Android中Serializable和Parcelable序列化对象详解

Android中如何使用Intent在Activity之间传递对象[使用Serializable或者Parcelable]