且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

通过类转换异常时Serializables阵列从一个活动到另一个

更新时间:2023-11-27 12:40:46

显然,这是对旧版Android的一个bug。 (版本5.0.1测试是唯一的版本上它像预期的那样,也许是5.0及以上的作品)

的错误

假设我们有一个名为对象,实施序列化名为用户

的数组
 用户[]用户;

当我们试图通过这样一个意图通过这个阵列到另一个活动

  intent.putExtra(的myKey用户);

我们的用户将被转换为对象[]

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

 用户[] =用户getIntent()getSerializableExtra(的myKey);

我们会得到一个ClassCastException。

从文档,我们可以得出结论,这不应该是一个问题,因为阵列是一个序列化的类,而 putExtra(字符串键,序列化值)已自加入 API 1

如果你想先传递一个阵列透过Android版本的意图到Android 5.0.1(也许一些老版本的藏汉工作,但到Android 4.3版本的是不工作)
你必须解决它。你可以通过你的阵列转换为做到这一点的的ArrayList

修改

另一个解决方法是复制你的额外到一个新的数组,因此不必强制转换。我不知道的方法,虽然正/负面影响。它是这样的:

 对象[]数组=(对象[])getIntent()getSerializableExtra(密钥)。
网友[] = parsedArray Arrays.copyOf(数组,array.length,用户[]类);

在这里我发现这个方法:How为对象数组转换为字符串数组在Java中。

I have an array containing serializable objects and am trying to use Intent's putExtra() and Bundle's getSerializable(). However, I am getting a class cast exception and don't understand why.

Below is the code. UserInfo is my own class which implements Serializable, and I have been able to pass individual UserInfo objects between activities. I've only ran into this problem when attempting to use an array.

Code sending the serializable:

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

Code retrieving the serializable:

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

Here is the error:

Question

I'm aware I could probably just use a different data structure, but I would like to understand why the array does not work since arrays are serializable?

EDIT: SnyersK was able to get a simpler but similar scenario to work. So I tried the same thing, and I still get the same exception. It turned my array of Tests into an Object when retrieving the array, which results in the casting exception.

My Test object:

package types;

import java.io.Serializable;

public class Test implements Serializable {

    private static final long serialVersionUID = 1L;

    private String hello = "hello";

}

Code to pass the array of Test objects:

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

Code to retrieve the array of Test objects:

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

Apparently this is a bug on older versions of Android. (Version 5.0.1 is the only version tested on which it works like expected, perhaps it works from 5.0 and up)

The bug

Let's say we have an Array of an object called which implements Serializable named User.

User[] users;

When we try to pass this array to another activity through an intent like this

intent.putExtra("myKey", users);

our users will get converted to Object[].

If we try to get our array from the intent in the second activity like so

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

We will get a ClassCastException.

From the docs, we can conclude that this shouldn't be a problem since Array is a serializable class, and putExtra(String key, Serializable value) has been added since api 1.

If you want to pass an Array through an intent on Android versions prior to Android 5.0.1 (maybe some older versions work aswell, but up to Android 4.3 it is NOT working) You'll have to work around it. You could do this by converting your Array to an ArrayList.

EDIT

another workaround is copying your extra to a new array, thus, not having to cast it. I'm not sure about the positive/negative consequences of the method though. It would look like this:

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

I found this method here: How to convert object array to string array in Java.