Android E/Parcel: класс не найден при разборке (только на Samsung Tab3)
Мне не удалось решить, почему эта ошибка возникает, и только на устройстве Samsung Tab3, работающем на 4.4.2? Это происходит, когда моя MainActivity запускает другое действие и передает класс Parcelable в следующем порядке:
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 получает сравнимые данные:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
TestParcel cfgOptions = getIntent().getExtras().getParcelable("cfgOptions");
}
Класс 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];
}
};
}
Опять же, я вижу это только на устройстве Samsung Tab3, но это устройство, в котором мы должны работать. Здесь logcat samsung:
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
По какой-то странной причине похоже, что загрузчик классов не настроен должным образом.
Попробуйте выполнить одно из следующих действий в 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");
В качестве альтернативы оберните фрагмент в пакет:
Bundle b = new Bundle();
b.putParcelable("options", cfgOptions);
Intent intent = new Intent(MDex.this, TestActivity.class);
intent.putExtra("bundle", b);
чтобы получить:
Bundle b = getIntent().getBundleExtra("bundle");
TestParcel cfgOptions = b.getParcelable("options");
Ответ 2
В моем случае новый Intent(). putExtra (key, parcelable), который внутренне автоматически создает новый пакет, дает мне ошибку unmarshall. Я не знаю почему, поэтому мне пришлось создать новый пакет один раз, добавить на него подробный и добавьте связку в намерение. Делая это, он решает проблему.
Ответ 3
Просто стараюсь быть более кратким и без ответа отсюда -
//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
Та же самая проблема произошла со мной с недавним телефоном Samsung S8. Создание пакета явно работало для меня. Я использовал следующий код, который не требует строкового идентификатора для пакета:
// 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);
А затем прочитайте посылку обратно в упражнении:
// In your activity, read parcelable back.
YourParcelable p = getIntent().getParcelableExtra("YOUR_PARCELABLE_ID");
Надеюсь, это поможет.
Ответ 5
Может быть полезно людям, которые смешивают Java с Kotlin.
Я нашел простое решение, которое позволяет использовать только Kotlin и без шаблона.
val intent = Intent(this, TestActivity::class.java).apply {
extras?.putParcellable("cfgOptions", cfgOptions)
}
startActivityForResult(intent, DBG_TEST);
А затем для списания значения, которое вы должны использовать:
var cfgOptions = intent?.extras?.getParcellable<TestParcel>("cfgOptions")
Ответ 6
Для людей, которые используют Java и Kotlin в вашем проекте, вы можете столкнуться с такого рода ошибкой, если вы создаете Parcelable Data Class
в kotlin, и вы используете его в Java Class eg Activity or something
, это кажется проблемой, и ее решение просто использовать вместо этого Java POJOs
, если класс данных kotlin
Ответ 7
Просто нашел еще одну причину этого исключения. По какой-то причине я получил его только тогда, когда активность была восстановлена, но не когда она была создана впервые.
Если ваша отправляемая сущность - kotlin data class
, которая является дочерней по отношению к некоторому class
, и вы пытаетесь ее разархивировать, вы можете получить BadParcelableException, класс не найден при отмене сортировки.
Решение состоит в том, чтобы сделать такой класс просто class
, а не data class
.