将Serializable数组从一个活动传递到另一个活动时的类Cast Exception

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将Serializable数组从一个活动传递到另一个活动时的类Cast Exception相关的知识,希望对你有一定的参考价值。

我有一个包含可序列化对象的数组,我试图使用Intent的putExtra()和Bundle的getSerializable()。但是,我得到一个类强制转换异常并且不明白为什么。

下面是代码。 UserInfo是我自己的类,它实现了Serializable,我能够在活动之间传递单个UserInfo对象。我在尝试使用数组时遇到了这个问题。

发送序列化的代码:

Intent intent = new Intent( JOIN_GROUP ); //JOIN_GROUP is a constant string

String user_ids[] = packet.userIDs();

int length = user_ids.length;
UserInfo users[] = new UserInfo[length];

for ( int i = 0; i < length; ++i )
    users[i] = getUserByID( user_ids[i] );

intent.putExtra( USERS_IN_GROUP, users );

检索序列化的代码:

Bundle extra = intent.getExtras();          
String action = intent.getAction();

if ( action.equals(IMService.JOIN_GROUP) )
{   
    //CLASS CAST EXCEPTION
    UserInfo users[] = (UserInfo[]) extra.getSerializable( IMService.USERS_IN_GROUP ); 
}

这是错误:

我知道我可能只是使用不同的数据结构,但我想理解为什么数组不可行,因为数组是可序列化的?

编辑:SnyersK能够得到一个更简单但类似的方案来工作。所以我尝试了同样的事情,我仍然得到同样的例外。在检索数组时,它将我的Tests数组转换为Object,这导致了转换异常。

我的测试对象:

package types;

import java.io.Serializable;

public class Test implements Serializable {

    private static final long serialVersionUID = 1L;

    private String hello = "hello";

}

传递Test对象数组的代码:

Test myArray[] = new Test[] { new Test(), new Test() };
Intent i = new Intent( this, Login.class );
i.putExtra( "key", myArray );

用于检索Test对象数组的代码:

Bundle extras = getIntent().getExtras();
Test array[] = (Test[]) extras.getSerializable( "key" ); //Class Cast Exception
答案

显然这是旧版android的错误。 (版本5.0.1是唯一经过测试的版本,它可以像预期的那样工作,也许它适用于5.0及以上版本)

错误

假设我们有一个名为User的对象数组,它实现了Serializable

User[] users;

当我们尝试通过这样的意图将此数组传递给另一个活动时

intent.putExtra("myKey", users);

我们的users将转换为Object[]

如果我们试图从第二个活动的意图中获取我们的数组,就像这样

User[] users = getIntent().getSerializableExtra("myKey");

我们将得到一个ClassCastException。

从文档中,我们可以得出结论,这不应该是一个问题,因为Array是一个可序列化的类,并且自putExtra(String key, Serializable value)以来添加了api 1

如果你想在Android 5.0.1之前的Android版本上通过一个Array(也许一些旧版本可以工作,但是直到Android 4.3它还没有工作)你将不得不解决它。您可以通过将Array转换为ArrayList来实现此目的。

编辑

另一种解决方法是将你的额外复制到一个新数组,因此,不必抛出它。我不确定该方法的积极/消极后果。它看起来像这样:

Object[] array = (Object[]) getIntent().getSerializableExtra("key");
User[] parsedArray = Arrays.copyOf(array, array.length, User[].class);

我在这里找到了这个方法:How to convert object array to string array in Java

另一答案

更换

intent.putExtra( USERS_IN_GROUP, users );

intent.putExtra( USERS_IN_GROUP, new ArrayList<UserInfo>(Arrays.asList(users)));
另一答案

试试这样:

Intent intent = new Intent( JOIN_GROUP ); //JOIN_GROUP is a constant string

String user_ids[] = packet.userIDs();

int length = user_ids.length;
UserInfo users[] = new UserInfo[length];

for ( int i = 0; i < length; ++i )
    users[i] = getUserByID( user_ids[i] );

Bundle bnd=new Bundle();
bnd.putSerializable(USERS_IN_GROUP, users);

虽然发送给你的是附加意图,但是当你正在阅读时,你正在从捆绑中读取(这是额外的意图)。

另一答案

UserInfo内部类还是单独的java类文件?

如果它是内部类,那么父类也应该是Serializable。

如果没有,请使UserInfo类实现Parcelable并使用

intent.putParcelableArrayListExtra(USERS_IN_GROUP, new ArrayList<UserInfo>(Arrays.asList(users)));
另一答案

在doc HERE,没有putExtra(String name, Serializable[] value)方法(注意[]括号)。只有putExtra(String name, Serializable value) - 单个可序列化对象。

你应该尝试使用Parcelable - 意图可以携带额外的一个对象和数组

以上是关于将Serializable数组从一个活动传递到另一个活动时的类Cast Exception的主要内容,如果未能解决你的问题,请参考以下文章

如何将 LatLng 的数组列表从一个活动传递到另一个活动

将 Serializables 数组从一个活动传递到另一个活动时发生 Class Cast Exception

无法通过intent将数组列表从一个活动传递到另一个活动

通过DrawerNavigator中的StackNavigator将数据从一页传递到另一页

将 listView 数据从一个活动发送到另一个活动

如何将图像从一项活动发送到另一项活动?