Class 将可序列化数组从一个 activity 传递到另一个时抛出异常
Class Cast Exception when passing array of Serializables from one activity to another
我有一个包含可序列化对象的数组,我正在尝试使用 Intent 的 putExtra() 和 Bundle 的 getSerializable()。但是,我得到一个 class 强制转换异常并且不明白为什么。
下面是代码。 UserInfo 是我自己的 class,它实现了 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 能够得到一个更简单但相似的场景来工作。
所以我尝试了同样的事情,但我仍然得到同样的异常。它在检索数组时将我的测试数组变成了一个对象,这导致了转换异常。
我的测试对象:
package types;
import java.io.Serializable;
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
private String hello = "hello";
}
传递测试对象数组的代码:
Test myArray[] = new Test[] { new Test(), new Test() };
Intent i = new Intent( this, Login.class );
i.putExtra( "key", myArray );
检索测试对象数组的代码:
Bundle extras = getIntent().getExtras();
Test array[] = (Test[]) extras.getSerializable( "key" ); //Class Cast Exception
替换
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);
在发送时您正在附加到意图,而在返回时您正在从包中读取(这是意图附加)。
显然这是旧版本 Android 上的错误。 (版本 5.0.1 是唯一一个按预期工作的测试版本,也许它可以从 5.0 及更高版本开始工作)
错误
假设我们有一个名为 User
的对象数组,它实现了 Serializable
.
User[] users;
当我们尝试通过这样的意图将此数组传递给另一个activity时
intent.putExtra("myKey", users);
我们的 users
将转换为 Object[]
。
如果我们尝试从第二个 activity 中的意图中获取我们的数组,就像这样
User[] users = getIntent().getSerializableExtra("myKey");
我们将得到一个 ClassCastException。
从文档中,我们可以得出结论,这应该不是问题,因为 Array
是可序列化的 class,并且自 api 1
以来添加了 putExtra(String key, Serializable value)
.
如果你想通过 Android 5.0.1 之前的 Android 版本的意图传递 Array
(也许一些旧版本也可以,但最多 Android 4.3 它不工作)
你必须解决它。您可以通过将 Array
转换为 ArrayList
.
来做到这一点
编辑
另一种解决方法是将您的额外内容复制到一个新数组中,因此不必强制转换它。不过,我不确定该方法的 positive/negative 后果。它看起来像这样:
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。
UserInfo
是内部 class 还是单独的 java class 文件?
如果它是内部 class,那么父 class 也应该是可序列化的。
如果没有,使 UserInfo
class 实施 Parcelable
并使用
intent.putParcelableArrayListExtra(USERS_IN_GROUP, new ArrayList<UserInfo>(Arrays.asList(users)));
我有一个包含可序列化对象的数组,我正在尝试使用 Intent 的 putExtra() 和 Bundle 的 getSerializable()。但是,我得到一个 class 强制转换异常并且不明白为什么。
下面是代码。 UserInfo 是我自己的 class,它实现了 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 能够得到一个更简单但相似的场景来工作。 所以我尝试了同样的事情,但我仍然得到同样的异常。它在检索数组时将我的测试数组变成了一个对象,这导致了转换异常。
我的测试对象:
package types;
import java.io.Serializable;
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
private String hello = "hello";
}
传递测试对象数组的代码:
Test myArray[] = new Test[] { new Test(), new Test() };
Intent i = new Intent( this, Login.class );
i.putExtra( "key", myArray );
检索测试对象数组的代码:
Bundle extras = getIntent().getExtras();
Test array[] = (Test[]) extras.getSerializable( "key" ); //Class Cast Exception
替换
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);
在发送时您正在附加到意图,而在返回时您正在从包中读取(这是意图附加)。
显然这是旧版本 Android 上的错误。 (版本 5.0.1 是唯一一个按预期工作的测试版本,也许它可以从 5.0 及更高版本开始工作)
错误
假设我们有一个名为 User
的对象数组,它实现了 Serializable
.
User[] users;
当我们尝试通过这样的意图将此数组传递给另一个activity时
intent.putExtra("myKey", users);
我们的 users
将转换为 Object[]
。
如果我们尝试从第二个 activity 中的意图中获取我们的数组,就像这样
User[] users = getIntent().getSerializableExtra("myKey");
我们将得到一个 ClassCastException。
从文档中,我们可以得出结论,这应该不是问题,因为 Array
是可序列化的 class,并且自 api 1
以来添加了 putExtra(String key, Serializable value)
.
如果你想通过 Android 5.0.1 之前的 Android 版本的意图传递 Array
(也许一些旧版本也可以,但最多 Android 4.3 它不工作)
你必须解决它。您可以通过将 Array
转换为 ArrayList
.
编辑
另一种解决方法是将您的额外内容复制到一个新数组中,因此不必强制转换它。不过,我不确定该方法的 positive/negative 后果。它看起来像这样:
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。
UserInfo
是内部 class 还是单独的 java class 文件?
如果它是内部 class,那么父 class 也应该是可序列化的。
如果没有,使 UserInfo
class 实施 Parcelable
并使用
intent.putParcelableArrayListExtra(USERS_IN_GROUP, new ArrayList<UserInfo>(Arrays.asList(users)));