LinkedList的投入额外的意向被改写的下一个活动时,检索到ArrayList中 [英] LinkedList put into Intent extra gets recast to ArrayList when retrieving in next activity

查看:112
本文介绍了LinkedList的投入额外的意向被改写的下一个活动时,检索到ArrayList中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个行为我正在观察WRT传递序列化的数据作为额外的意图是很奇怪的,我只是想澄清是否有什么东西我不会错过了。

A behaviour i'm observing w.r.t passing serializable data as intent extra is quite strange, and I just wanted to clarify whether there's something I'm not missing out on.

于是事情,我试图做的是,在 ActivtyA 我把的LinkedList 实例到意图我启动下一个活动创建 - ActivityB

So the thing I was trying to do is that in ActivtyA I put a LinkedList instance into the intent I created for starting the next activity - ActivityB.

LinkedList<Item> items = (some operation);
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra(AppConstants.KEY_ITEMS, items);

的onCreate ActivityB 中,我试图找回的LinkedList 额外如下 -

In the onCreate of ActivityB, I tried to retrieve the LinkedList extra as follows -

LinkedList<Item> items = (LinkedList<Item>) getIntent()
                             .getSerializableExtra(AppConstants.KEY_ITEMS);

在运行此,我多次得到了 ClassCastException异常 ActivityB ,在该行以上。基本上,除了说我收到的ArrayList 。有一次,我改变了code以上,以接收的ArrayList 代替,一切工作就好了。

On running this, I repeatedly got a ClassCastException in ActivityB, at the line above. Basically, the exception said that I was receiving an ArrayList. Once I changed the code above to receive an ArrayList instead, everything worked just fine.

现在我不能只从现有的文件弄清楚这是否通过序列化List实现的时候是在Android上预期的行为。或许,有一些根本性错误瓦特/我在做什么。

Now I can't just figure out from the existing documentation whether this is the expected behaviour on Android when passing serializable List implementations. Or perhaps, there's something fundamentally wrong w/ what I'm doing.

感谢。

推荐答案

我可以告诉你为什么会这样,但你不会喜欢它, - )

I can tell you why this is happening, but you aren't going to like it ;-)

首先一点背景资料:

其他意图基本上是一个Android 捆绑这基本上是一个< code键/值对>的HashMap 。所以,当你做这样的事情

Extras in an Intent are basically an Android Bundle which is basically a HashMap of key/value pairs. So when you do something like

intent.putExtra(AppConstants.KEY_ITEMS, items);

安卓创建一个新的捆绑的群众演员,并增加了一个映射条目到捆绑,其中最关键的是 AppConstants.KEY_ITEMS 和值(这是你的LinkedList对象)。

Android creates a new Bundle for the extras and adds a map entry to the Bundle where the key is AppConstants.KEY_ITEMS and the value is items (which is your LinkedList object).

这是一切优秀和良好的,以后你的code。如果你看演员捆绑执行您会发现它包含了一个的LinkedList 。现在到了有趣的部分...

This is all fine and good, and if you were to look at the extras bundle after your code executes you will find that it contains a LinkedList. Now comes the interesting part...

当你调用 startActivity()与含额外意图,机器人需要的额外转换键/值对映射成一个字节流。基本上,它需要为序列化的捆绑。它需要做,因为它可能会开始活动的另一个进程中,为了做到这点,需要序列化/反序列化被捆绑的对象,以便它可以重新创建新进程。它也需要这样做是因为机器人保存意图的内容在某些系统表,以便它可以再生意图是否需要购买。

When you call startActivity() with the extras-containing Intent, Android needs to convert the extras from a map of key/value pairs into a byte stream. Basically it needs to serialize the Bundle. It needs to do that because it may start the activity in another process and in order to do that it needs to serialize/deserialize the objects in the Bundle so that it can recreate them in the new process. It also needs to do this because Android saves the contents of the Intent in some system tables so that it can regenerate the Intent if it needs to later.

为了给捆绑序列化为字节流,它通过被捆绑的地图,并得到每个键/值对。然后它拍摄的价值(这是某种对象),并试图确定它是哪种对象,以便它可以以最有效的方式把它序列。要做到这一点,它会针对众所周知的对象类型的列表中选择对象类型。 已知的对象类型列表中包含像整数字符串地图捆绑不幸的是还列表。因此,如果对象是一个列表(其中有许多不同种类,其中包括的LinkedList )将其序列,并标记这类型的对象列表

In order to serialize the Bundle into a byte stream, it goes through the map in the bundle and gets each key/value pair. Then it takes each "value" (which is some kind of object) and tries to determine what kind of object it is so that it can serialize it in the most efficient way. To do this, it checks the object type against a list of known object types. The list of "known object types" contains things like Integer, Long, String, Map, Bundle and unfortunately also List. So if the object is a List (of which there are many different kinds, including LinkedList) it serializes it and marks it as an object of type List.

捆绑进行反序列化,即:当你做到这一点:

When the Bundle is deserialized, ie: when you do this:

LinkedList<Item> items = (LinkedList<Item>)
        getIntent().getSerializableExtra(AppConstants.KEY_ITEMS);

它会产生一个的ArrayList 捆绑类型列表中的所有对象

确实没有什么可以做改变Android的这种行为。至少现在你知道它为什么做这个。

There isn't really anything you can do to change this behaviour of Android. At least now you know why it does this.

只是让你知道:其实我写了一个小的测试程序来验证这种行为,我已经看过源$ C ​​$下 Parcel.writeValue(宾语)这是被从捆绑时,地图上成字节流的转换。调用的方法

Just so that you know: I actually wrote a small test program to verify this behaviour and I have looked at the source code for Parcel.writeValue(Object v) which is the method that gets called from Bundle when it converts the map into a byte stream.

重要提示:由于列表是一个接口,这意味着任何类实现列表您放入捆绑将出来作为一个的ArrayList 。 这也是有趣的是,地图也是已知的对象类型,这意味着,无论是哪一种地图对象,你把一个捆绑(例如 TreeMap的的SortedMap ,或实现地图接口的任何类),你总是会得到一个的HashMap 出来。

Important Note: Since List is an interface this means that any class that implements List that you put into a Bundle will come out as an ArrayList. It is also interesting that Map is also in the list of "known object types" which means that no matter what kind of Map object you put into a Bundle (for example TreeMap, SortedMap, or any class that implements the Map interface), you will always get a HashMap out of it.

这篇关于LinkedList的投入额外的意向被改写的下一个活动时,检索到ArrayList中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆