web-dev-qa-db-fra.com

Android E / Colis Classe non trouvée lors de la suppression (uniquement sur Samsung Tab3)

Je ne parviens pas à résoudre la cause de cette erreur, et uniquement sur un périphérique Samsung Tab3, fonctionnant sous 4.4.2? Cela se produit lorsque ma MainActivity commence une autre activité et passe une classe Parcelable dans l'intention comme suit:

    private void debugTest(TestParcel cfgOptions){
        TestParcel cfgOptions = new TestParcel();
        cfgOptions.setValue(15); //just to verify

        Intent intent = new Intent(MainActivity.this, TestActivity.class);
        intent.putExtra("cfgOptions", cfgOptions);
        startActivityForResult(intent, DBG_TEST);
    }

TestActivity récupère les données parcellaires de la manière suivante:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_activity);

    TestParcel cfgOptions = getIntent().getExtras().getParcelable("cfgOptions");
}

La classe TestParcel:

    import Android.os.Parcel;
    import Android.os.Parcelable;

    public class TestParcel implements Parcelable {
    private long l_ucs_value = 0;
    private String s_rx_number = "";

    //constructor
    public TestParcel() {
        l_ucs_value = 0;
        s_rx_number = "";
    }

    public void RxNumber(String s) {
        s_rx_number = s;
    }
    public String RxNumber() {
        return s_rx_number;
    }

    //-----------------------------------------------------------------------
    public void setValue(long v){
        l_ucs_value = v;
    }
    public long getValue(){ return l_ucs_value; }


    protected TestParcel(Parcel in) {
        l_ucs_value = in.readLong();
        s_rx_number = in.readString();
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(l_ucs_value);
        dest.writeString(s_rx_number);
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<TestParcel> CREATOR = new Parcelable.Creator<TestParcel>() {
        @Override
        public TestParcel createFromParcel(Parcel in) {
            return new TestParcel(in);
        }

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

Encore une fois, je ne vois cela que sur le périphérique Samsung Tab3 - mais c’est le périphérique sur lequel nous avons besoin de travailler. Voici le samsung logcat:

02-18 08:05:55.393    2235-2571/? E/Parcel? Class not found when unmarshalling: com.vms.Android.VersatileDEX.TestParcel
Java.lang.ClassNotFoundException: com.vms.Android.VersatileDEX.TestParcel
        at Java.lang.Class.classForName(Native Method)
        at Java.lang.Class.forName(Class.Java:251)
        at Java.lang.Class.forName(Class.Java:216)
        at Android.os.Parcel.readParcelableCreator(Parcel.Java:2133)
        at Android.os.Parcel.readParcelable(Parcel.Java:2097)
        at Android.os.Parcel.readValue(Parcel.Java:2013)
        at Android.os.Parcel.readArrayMapInternal(Parcel.Java:2314)
        at Android.os.Bundle.unparcel(Bundle.Java:249)
        at Android.os.Bundle.getString(Bundle.Java:1118)
        at Android.content.Intent.getStringExtra(Intent.Java:5148)
        at com.Android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.Java:1467)
        at com.Android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.Java:1063)
        at com.Android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.Java:4134)
        at com.Android.server.am.ActivityManagerService.startActivity(ActivityManagerService.Java:4032)
        at Android.app.ActivityManagerNative.onTransact(ActivityManagerNative.Java:159)
        at com.Android.server.am.ActivityManagerService.onTransact(ActivityManagerService.Java:2712)
        at Android.os.Binder.execTransact(Binder.Java:404)
        at dalvik.system.NativeStart.run(Native Method)
 Caused by: Java.lang.NoClassDefFoundError: com/vms/Android/VersatileDEX/TestParcel
        at Java.lang.Class.classForName(Native Method)
        at Java.lang.Class.forName(Class.Java:251)
        at Java.lang.Class.forName(Class.Java:216)
        at Android.os.Parcel.readParcelableCreator(Parcel.Java:2133)
        at Android.os.Parcel.readParcelable(Parcel.Java:2097)
        at Android.os.Parcel.readValue(Parcel.Java:2013)
        at Android.os.Parcel.readArrayMapInternal(Parcel.Java:2314)
        at Android.os.Bundle.unparcel(Bundle.Java:249)
        at Android.os.Bundle.getString(Bundle.Java:1118)
        at Android.content.Intent.getStringExtra(Intent.Java:5148)
        at com.Android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.Java:1467)
        at com.Android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.Java:1063)
        at com.Android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.Java:4134)
        at com.Android.server.am.ActivityManagerService.startActivity(ActivityManagerService.Java:4032)
        at Android.app.ActivityManagerNative.onTransact(ActivityManagerNative.Java:159)
        at com.Android.server.am.ActivityManagerService.onTransact(ActivityManagerService.Java:2712)
        at Android.os.Binder.execTransact(Binder.Java:404)
        at dalvik.system.NativeStart.run(Native Method)
 Caused by: Java.lang.ClassNotFoundException: Didn't find class "com.vms.Android.VersatileDEX.TestParcel" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.Java:67)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:497)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:457)
        at Java.lang.Class.classForName(Native Method)
        at Java.lang.Class.forName(Class.Java:251)
        at Java.lang.Class.forName(Class.Java:216)
        at Android.os.Parcel.readParcelableCreator(Parcel.Java:2133)
        at Android.os.Parcel.readParcelable(Parcel.Java:2097)
        at Android.os.Parcel.readValue(Parcel.Java:2013)
        at Android.os.Parcel.readArrayMapInternal(Parcel.Java:2314)
        at Android.os.Bundle.unparcel(Bundle.Java:249)
        at Android.os.Bundle.getString(Bundle.Java:1118)
        at Android.content.Intent.getStringExtra(Intent.Java:5148)
        at com.Android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.Java:1467)
        at com.Android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.Java:1063)
        at com.Android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.Java:4134)
        at com.Android.server.am.ActivityManagerService.startActivity(ActivityManagerService.Java:4032)
        at Android.app.ActivityManagerNative.onTransact(ActivityManagerNative.Java:159)
        at com.Android.server.am.ActivityManagerService.onTransact(ActivityManagerService.Java:2712)
        at Android.os.Binder.execTransact(Binder.Java:404)
        at dalvik.system.NativeStart.run(Native Method)
45
J Avery

Pour une raison étrange, il semble que le chargeur de classes ne soit pas configuré correctement.

Essayez l’une des choses suivantes dans TestActivity.onCreate():


TestParcel cfgOptions = getIntent().getParcelableExtra("cfgOptions");

Intent intent = getIntent();
intent.setExtrasClassLoader(TestParcel.class.getClassLoader());
TestParcel cfgOptions = intent.getParcelableExtra("cfgOptions");

Bundle extras = getIntent().getExtras();
extras.setClassLoader(TestParcel.class.getClassLoader());
TestParcel cfgOptions = extras.getParcelable("cfgOptions");

Vous pouvez également emballer le colis dans un paquet:

Bundle b = new Bundle();
b.putParcelable("options", cfgOptions);
Intent intent = new Intent(MDex.this, TestActivity.class);
intent.putExtra("bundle", b);

obtenir:

Bundle b = getIntent().getBundleExtra("bundle");
TestParcel cfgOptions = b.getParcelable("options");
72
David Wasser

Dans mon cas, le nouvel Intent (). PutExtra (clé, parcelable) qui crée automatiquement un nouveau paquet me donne une erreur inouïe. Je ne sais pas pourquoi. J'ai donc dû créer un nouveau paquet tout seul, ajouter le paquet bundle sur l'intention. Ce faisant, le problème est résolu.

8
Flux

J'essaie juste d'être plus concis et plus clair dans la réponse ici -

//sending a parcelable class to another activity -----------------

MyParcelableOptionsClass mpoc = new MyParcelableOptionsClass();

Bundle b = new Bundle();
b.putParcelable("options", mpoc );

Intent intent = new Intent(MyActivity.this, OtherActivity.class);
intent.putExtra("bundle", b);

startActivityForResult(intent, 1);


//getting the parcelable class from OtherActivity------------------

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.other_activity);

    Bundle b = getIntent().getBundleExtra("bundle");
    MyParcelableOptionsClass mpoc = b.getParcelable("options");
}


//returning the parcelable class back from OtherActivity -----------

 Bundle b = new Bundle();
 b.putParcelable("options", mpoc);

 Intent intent = new Intent();
 intent.putExtra("bundle", b);

 setResult(0, intent);


//and getting the parcelable class back in MyActivity --------------

onActivityResult(int requestCode, int resultCode, Intent data){
    if(null != data){
        Bundle b = data.getBundleExtra("bundle");
        MyParcelableOptionsClass mpoc = b.getParcelable("options");
    }
}
7
J Avery

Le même problème m'est arrivé avec un téléphone Samsung S8 récent. Créer le paquet a fonctionné explicitement pour moi. J'ai utilisé le code suivant, qui ne nécessite pas d'identifiant de chaîne pour le bundle:

// Create the intent to start the activity.
Bundle bundle = new Bundle();
bundle.putParcelable("YOUR_PARCELABLE_ID", yourPacelable);
Intent intent = new Intent(context, YourActivity.class);
intent.putExtras(bundle);

Et puis relisez le colis dans l'activité:

// In your activity, read parcelable back.
YourParcelable p = getIntent().getParcelableExtra("YOUR_PARCELABLE_ID");

J'espère que ça aide.

4
crazypeter

Peut être utile pour les personnes qui mélangent Java avec Kotlin. J'ai trouvé une solution simple qui permet d'utiliser uniquement Kotlin et sans passe-partout.

val intent = Intent(this, TestActivity::class.Java).apply {
    extras?.putParcellable("cfgOptions", cfgOptions)
}

startActivityForResult(intent, DBG_TEST);

Et puis pour retirer la valeur que vous devriez utiliser:

var cfgOptions = intent?.extras?.getParcellable<TestParcel>("cfgOptions")
1
Blake

Je viens de trouver une autre cause de cette exception. Pour une raison quelconque, je ne l'ai eu que lorsque l'activité a été restaurée, mais pas lors de sa création. Si votre entité parcellaire est kotlin data class qui est enfant de class, et que vous essayez de le défaire, vous obtiendrez peut-être BadParcelableException, classe introuvable lors de la restarification. La solution est de faire en sorte que cette classe ne soit que class, pas data class.

0
Shramov

Pour les personnes utilisant à la fois Java et Kotlin dans votre projet, vous risquez de rencontrer ce type d'erreur si vous créez un fichier Parcelable Data Class en kotlin et vous l’utilisez en Java Class eg Activity or something, cela semble être un problème et sa solution consiste simplement à utiliser Java POJOs à la place si la classe de données kotlin

0
Ahmed Elshaer