Android E/Parcel﹕;解组时找不到类(仅在Samsung Tab3上)

Android E/Parcel﹕;解组时找不到类(仅在Samsung Tab3上),android,android-intent,classnotfoundexception,unmarshalling,parcel,Android,Android Intent,Classnotfoundexception,Unmarshalling,Parcel,我一直无法解决为什么会发生此错误,而且只能在运行4.4.2的三星Tab3设备上发生?当我的MainActivity启动另一个活动,并以如下方式传递一个Parcelable类时,就会发生这种情况: private void debugTest(TestParcel cfgOptions){ TestParcel cfgOptions = new TestParcel(); cfgOptions.setValue(15); //just to verify

我一直无法解决为什么会发生此错误,而且只能在运行4.4.2的三星Tab3设备上发生?当我的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];
        }
    };
}

出于某种奇怪的原因,类装入器似乎没有正确设置

TestActivity.onCreate()中尝试以下操作之一:





或者,将包裹包裹成捆:

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

只是想更简洁明了地回答这个问题-

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

在我的例子中,new Intent().putExtra(key,parcelable)会在内部自动创建新的捆绑包,这会给我带来解组错误,我不知道为什么,所以我必须自己创建新捆绑包,在其上添加捆绑包并在Intent上添加捆绑包。通过这样做,它解决了问题。

同样的问题也发生在我最近的三星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");

我希望这会有所帮助。

对于在您的项目中同时使用Java和Kotlin的人,如果您在Kotlin中创建一个
Parcelable数据类,并且在
Java类eg活动或类似活动中使用它,您可能会遇到这种错误,这似乎是一个问题,它的解决方案只是使用
javapojo
,如果kotlin数据类对将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")
var cfgOptions=intent?.extras?.getParcellable(“cfgOptions”)

刚刚找到导致此异常的另一个原因。出于某种原因,我只在恢复活动时得到它,而不是在第一次创建活动时得到它。 如果您的parcelable实体是kotlin
数据类
,它是某些
的子类,并且您尝试对其进行解组,则在解组时可能会得到BadParcelableException,class not found。
解决方案是使这样的类只是
,而不是
数据类

我也有同样的问题。在我的例子中,intent的附加组件有两个带相同钥匙的可包裹对象。例如:

val intent = Intent()
val anotherIntent = Intent()

anotherIntent.putExtra("same_extra_key", MyParcelableObj())
intent.putExtra("same_extra_key", MyParcelableObj())

intent.putExtra("another_intent_extra_key", anotherIntent)

// ClassNotFoundError
intent.getParcelableExtra<MyParcelableObj>("same_extra_key")

我真的希望能成功,但这些情景都没有解决问题。我想知道这是否真的是三星特有的问题?该应用程序直到我(尽管我知道这些选项。我已经读到Bundles存储类名,所以我尝试了以下方法,并且成功了:当你的回答引导我解决问题时,我将在这里给你评分。发送:Bundle b=new Bundle();b.putParcelable(“options”,cfgooptions);Intent Intent=new Intent(MDex.this,TestActivity.class);intent.putExtra(“bundle”,b);to get:bundle b=getIntent().getBundleExtra(“bundle”);TestParcel cfgOptions=b.getParcelable(“options”);调用getParcelable()之前的行
bundle.setClassLoader(.class.getClassLoader());
)我只是在我们的三星测试设备上发现了这个错误——打包成一个包似乎可以确保Android的类加载器处理(un)编组,而不是一些定制的三星代码。我在三星Tab3中遇到了同样的解编错误,并尝试了几乎所有可能的解决方案,包括您的解决方案,但似乎没有一个解决问题,直到我更新到最新版本的安卓Studio 1.3.1,最终解决了这个问题。更新到最新版本,清理项目并重建它我会的。非常感谢。你的解决方案非常简单。三星J5确认了你知道这方面的任何参考/建议吗?
// In your activity, read parcelable back.
YourParcelable p = getIntent().getParcelableExtra("YOUR_PARCELABLE_ID");
val intent = Intent(this, TestActivity::class.java).apply {
    extras?.putParcellable("cfgOptions", cfgOptions)
}

startActivityForResult(intent, DBG_TEST);
var cfgOptions = intent?.extras?.getParcellable<TestParcel>("cfgOptions")
val intent = Intent()
val anotherIntent = Intent()

anotherIntent.putExtra("same_extra_key", MyParcelableObj())
intent.putExtra("same_extra_key", MyParcelableObj())

intent.putExtra("another_intent_extra_key", anotherIntent)

// ClassNotFoundError
intent.getParcelableExtra<MyParcelableObj>("same_extra_key")
intent.getParcelableArrayListExtra<MyParcelableObj>("same_extra_key")