web-dev-qa-db-fra.com

Classe non trouvée lorsque Unmarshalling Android Intent Parcelable

J'ai un ArrayList que je passe entre activities. Dans ce ArrayList sont des objets fabriqués à partir d'un class qui contient quatre variables. L'une de ces variables est une autre ArrayList<object> qui provient d'un autre class.

J'ai implémenté Parcelable sur les deux et je suis presque sûr d'avoir correctement exécuté les méthodes parcelables. Voici les erreurs:

Erreurs:

03-18 02:37:27.063: D/dalvikvm(3249): GC_FOR_ALLOC freed 82K, 6% free 3020K/3180K, paused 1ms, total 3ms
03-18 02:37:27.093: I/dalvikvm-heap(3249): Grow heap (frag case) to 3.626MB for 635808-byte allocation
03-18 02:37:27.103: D/dalvikvm(3249): GC_FOR_ALLOC freed 5K, 5% free 3635K/3804K, paused 10ms, total 10ms
03-18 02:37:27.173: D/(3249): HostConnection::get() New Host Connection established 0xb96396c0, tid 3249
03-18 02:37:27.243: W/EGL_emulation(3249): eglSurfaceAttrib not implemented
03-18 02:37:27.253: D/OpenGLRenderer(3249): Enabling debug mode 0
03-18 02:37:27.293: W/EGL_emulation(3249): eglSurfaceAttrib not implemented
03-18 02:37:32.383: D/dalvikvm(3249): GC_FOR_ALLOC freed 238K, 8% free 3911K/4224K, paused 1ms, total 1ms
03-18 02:37:32.383: E/Parcel(3249): Class not found when unmarshalling: com.example.Choices
03-18 02:37:32.383: E/Parcel(3249): Java.lang.ClassNotFoundException: com.example.Choices
03-18 02:37:32.383: E/Parcel(3249):     at Java.lang.Class.classForName(Native Method)
03-18 02:37:32.383: E/Parcel(3249):     at Java.lang.Class.forName(Class.Java:251)
03-18 02:37:32.383: E/Parcel(3249):     at Java.lang.Class.forName(Class.Java:216)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readParcelableCreator(Parcel.Java:2133)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readParcelable(Parcel.Java:2097)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readValue(Parcel.Java:2013)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readListInternal(Parcel.Java:2343)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readArrayList(Parcel.Java:1703)
03-18 02:37:32.383: E/Parcel(3249):     at com.example.midterm.Question.<init>(Question.Java:76)
03-18 02:37:32.383: E/Parcel(3249):     at com.example.midterm.Question$1.createFromParcel(Question.Java:98)
03-18 02:37:32.383: E/Parcel(3249):     at com.example.midterm.Question$1.createFromParcel(Question.Java:1)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readParcelable(Parcel.Java:2104)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readValue(Parcel.Java:2013)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readListInternal(Parcel.Java:2343)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readArrayList(Parcel.Java:1703)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readValue(Parcel.Java:2034)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Parcel.readArrayMapInternal(Parcel.Java:2314)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Bundle.unparcel(Bundle.Java:249)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Bundle.getParcelableArrayList(Bundle.Java:1250)
03-18 02:37:32.383: E/Parcel(3249):     at com.example.midterm.TriviaActivity.onCreate(TriviaActivity.Java:20)
03-18 02:37:32.383: E/Parcel(3249):     at Android.app.Activity.performCreate(Activity.Java:5231)
03-18 02:37:32.383: E/Parcel(3249):     at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1087)
03-18 02:37:32.383: E/Parcel(3249):     at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2159)
03-18 02:37:32.383: E/Parcel(3249):     at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2245)
03-18 02:37:32.383: E/Parcel(3249):     at Android.app.ActivityThread.access$800(ActivityThread.Java:135)
03-18 02:37:32.383: E/Parcel(3249):     at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1196)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Handler.dispatchMessage(Handler.Java:102)
03-18 02:37:32.383: E/Parcel(3249):     at Android.os.Looper.loop(Looper.Java:136)
03-18 02:37:32.383: E/Parcel(3249):     at Android.app.ActivityThread.main(ActivityThread.Java:5017)
03-18 02:37:32.383: E/Parcel(3249):     at Java.lang.reflect.Method.invokeNative(Native Method)
03-18 02:37:32.383: E/Parcel(3249):     at Java.lang.reflect.Method.invoke(Method.Java:515)
03-18 02:37:32.383: E/Parcel(3249):     at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:779)
03-18 02:37:32.383: E/Parcel(3249):     at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:595)
03-18 02:37:32.383: E/Parcel(3249):     at dalvik.system.NativeStart.main(Native Method)
03-18 02:37:32.383: E/Parcel(3249): Caused by: Java.lang.NoClassDefFoundError: com/example/midterm/Choices
03-18 02:37:32.383: E/Parcel(3249):     ... 34 more
03-18 02:37:32.383: E/Parcel(3249): Caused by: Java.lang.ClassNotFoundException: Didn't find class "com.example.midterm.Choices" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib]]
03-18 02:37:32.383: E/Parcel(3249):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.Java:56)
03-18 02:37:32.383: E/Parcel(3249):     at Java.lang.ClassLoader.loadClass(ClassLoader.Java:497)
03-18 02:37:32.383: E/Parcel(3249):     at Java.lang.ClassLoader.loadClass(ClassLoader.Java:457)
03-18 02:37:32.383: E/Parcel(3249):     ... 34 more
03-18 02:37:32.383: D/AndroidRuntime(3249): Shutting down VM
03-18 02:37:32.383: W/dalvikvm(3249): threadid=1: thread exiting with uncaught exception (group=0xb2cb8b20)
03-18 02:37:32.383: E/AndroidRuntime(3249): FATAL EXCEPTION: main
03-18 02:37:32.383: E/AndroidRuntime(3249): Process: com.example.midterm, PID: 3249
03-18 02:37:32.383: E/AndroidRuntime(3249): Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.TriviaActivity}: Android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.example.Choices
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2195)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2245)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.ActivityThread.access$800(ActivityThread.Java:135)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1196)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Handler.dispatchMessage(Handler.Java:102)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Looper.loop(Looper.Java:136)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.ActivityThread.main(ActivityThread.Java:5017)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Java.lang.reflect.Method.invokeNative(Native Method)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Java.lang.reflect.Method.invoke(Method.Java:515)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:779)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:595)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at dalvik.system.NativeStart.main(Native Method)
03-18 02:37:32.383: E/AndroidRuntime(3249): Caused by: Android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.example.midterm.Choices
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readParcelableCreator(Parcel.Java:2147)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readParcelable(Parcel.Java:2097)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readValue(Parcel.Java:2013)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readListInternal(Parcel.Java:2343)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readArrayList(Parcel.Java:1703)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at com.example.Question.<init>(Question.Java:76)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at com.example.midterm.Question$1.createFromParcel(Question.Java:98)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at com.example.midterm.Question$1.createFromParcel(Question.Java:1)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readParcelable(Parcel.Java:2104)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readValue(Parcel.Java:2013)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readListInternal(Parcel.Java:2343)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readArrayList(Parcel.Java:1703)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readValue(Parcel.Java:2034)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Parcel.readArrayMapInternal(Parcel.Java:2314)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Bundle.unparcel(Bundle.Java:249)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.os.Bundle.getParcelableArrayList(Bundle.Java:1250)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at com.example.midterm.TriviaActivity.onCreate(TriviaActivity.Java:20)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.Activity.performCreate(Activity.Java:5231)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1087)
03-18 02:37:32.383: E/AndroidRuntime(3249):     at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2159)
03-18 02:37:32.383: E/AndroidRuntime(3249):     ... 11 more

Comme vous pouvez le voir, la première erreur qui se produit est la classe non trouvée lors du dé-marshalling.

Voici mon code parcellable de classe Question:

/**
 * Constructs a Question from a Parcel
 * @param parcel Source Parcel
 */
public Question (Parcel parcel) {
    this.id = parcel.readString();
    this.text = parcel.readString();
    this.image = parcel.readString();
    this.choices = parcel.readArrayList(null);
}

@Override
public int describeContents() {
    return 0;
}

// Required method to write to Parcel
@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(id);
    dest.writeString(text);
    dest.writeString(image);
    dest.writeList(choices);
}

// Method to recreate a Question from a Parcel
public static Creator<Question> CREATOR = new Creator<Question>() {

    @Override
    public Question createFromParcel(Parcel source) {
        return new Question(source);
    }

    @Override
    public Question[] newArray(int size) {
        return new Question[size];
    }

};

et Choices, ma deuxième classe qui est insérée en tant qu'objet ArrayList dans Question:

/**
 * Constructs a Choice from a Parcel
 * @param parcel Source Parcel
 */
public Choices (Parcel parcel) {
    this.isCorrect = parcel.readByte() != 0;
    this.choice = parcel.readString();
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeByte((byte) (isCorrect ? 1 : 0));
    dest.writeString(choice);
}

// Method to recreate a Question from a Parcel
public static Creator<Choices> CREATOR = new Creator<Choices>() {

    @Override
    public Choices createFromParcel(Parcel source) {
        return new Choices(source);
    }

    @Override
    public Choices[] newArray(int size) {
        return new Choices[size];
    }

};

J'utilise ensuite le code suivant pour mettre un ArrayList<Question> dans l'intention:

Intent intent = new Intent(MainActivity.this, TriviaActivity.class);
intent.putParcelableArrayListExtra(QUESTION_KEY, questions);
startActivity(intent);

questions est la liste de tableaux. Je n'ai aucune erreur dans mon code et je ne peux pas comprendre où je me suis trompé. Toute aide est grandement appréciée!

18
Kenny

Vous devriez essayer de remplacer this.choices = parcel.readArrayList(null); par this.choices = parcel.readArrayList(Choices.class.getClassLoader());

J'espère que cela t'aides

21
k3v1n4ud3

Vous devez définir le ClassLoader. Essaye ça:

public Question (Parcel parcel) {
    this.id = parcel.readString();
    this.text = parcel.readString();
    this.image = parcel.readString();
    this.choices = parcel.readTypedList(Choices.class.getClassLoader());
}

Vous pouvez également essayer de lire et d'écrire une liste tapée au lieu d'un ArrayList:

public Question (Parcel parcel) {
    this.id = parcel.readString();
    this.text = parcel.readString();
    this.image = parcel.readString();
    this.choices = new ArrayList<Choices>();
    parcel.readArrayList(this.choices, Choices.Creator);
}
2
owe