Android E/Parcel: Class not found when unmarshalling (only on Samsung Tab3)

匿名 (未验证) 提交于 2019-12-03 01:51:02

问题:

I've been unable to resolve why this error occurs, and only on a Samsung Tab3 device, running 4.4.2? It happens when my MainActivity starts another Activity, and passes a Parcelable class in the intent like so:

    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 gets the parcelable data like so:

protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.test_activity);      TestParcel cfgOptions = getIntent().getExtras().getParcelable("cfgOptions"); } 

The class 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 CREATOR = new Parcelable.Creator() {         @Override         public TestParcel createFromParcel(Parcel in) {             return new TestParcel(in);         }          @Override         public TestParcel[] newArray(int size) {             return new TestParcel[size];         }     }; } 

Again, I only see this on the Samsung Tab3 device - but that's the device we need it to work on. Here's the 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) 

回答1:

For some strange reason it looks like the class loader isn't set up properly.

Try one of the following in 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"); 

Alternatively, wrap the parcelable into a bundle:

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

to get:

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


回答2:

In my case, new Intent().putExtra(key,parcelable) which internally auto creates new bundle gives me unmarshall error I don't know why, so I had to create new bundle by myself, add the parcelable on it and add the bundle on the intent. By doing so it solves the problem.



回答3:

Just trying to be more concise and clear of the answer here -

//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");     } } 


回答4:

The same issue happened to me with a recent Samsung S8 phone. Creating the bundle explicitly worked for me. I used the following code, which doesn't require a string identifier for the 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); 

And then read the parcelable back in the activity:

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

I hope this helps.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!