android - HashMap反序列化

标签 android serialization hashmap

我有一个服务器/客户端应用程序,我通过 Hessian/hessdroid 从服务器检索数据。数据非常复杂,HashMaps 包含其他 HashMaps 和存储在字节数组中的图像。我可以完美地显示数据。

为了不总是查询服务器,我使用数据结构作为缓存。我在关闭应用程序时使用 ObjectOutputStream 将此数据对象保存到 SD 卡。当我重新启动它时,我使用 ObjectInputStream 将其读回内存。

只有在从 SD 卡读取数据后,我才遇到应用程序问题。 LogCat 给我以下输出(100 次):

DEBUG/dalvikvm(4150): GetFieldID: unable to find field Ljava/util/HashMap;.loadFactor:F

这在其他消息之间:

INFO/dalvikvm-heap(4150): Grow heap (frag case) to 10.775MB for 281173-byte allocation

当堆增长到约 17 MB 时,应用程序崩溃。

我阅读了几个关于 HashMap 序列化的线程,在体系结构之间序列化时似乎存在错误,但对我来说,通过 Hessian 进行的数据传输工作得很好,我只有在从磁盘读取 HashMap 时才会遇到所描述的问题。

有什么想法吗?

最佳答案

正如 cyber-monk 评论的那样,该问题与 HashMap 反序列化没有直接关系。 Android 或它的 HashMap 实现中确实存在某种错误,但我认为这不是应用程序崩溃的原因。

现在我解决了这个问题,在应用程序中使用了更少的图像。例如,我有一个画廊,您可以在其中用脚蹼从一张图片滑动到下一张图片,然后一次加载所有图片。在一定数量的图像上,没有足够的堆空间。

我的解决方案是,不要一次保留所有解码图像。

它是这样完成的:

1) 将二进制图像数据保存在内存中(只要图像不是那么大就没有问题)

2) 在创建 flipper 的 View 时,不要将二进制图像数据加载到 ImageViews 中。

3) 将二进制图像数据设置到显示的ImageView中。

4) 保留下一个和上一个ImageView的二进制图像数据,更好的用户体验)

5) 通过将其资源设置为透明色来“卸载”未显示的ImageViews。

这是一些代码:

// initialize the viewFlipper by creating blank views
for (ComponentImageDto listElement : images) {
    LinearLayout view = renderView();
    flipper.addView(view);
}
showImage(flipper.getCurrentView());

renderView() 只返回一个包含 ImageView 的 LinearLayout

然后我写了一些方法来显示下一张/上一张图像,其中我将二进制数据设置为 ImageView:

private void showNextElement() {
    // show next flipper view
    flipper.showNext();

    // get current view
    int displayedChild = flipper.getDisplayedChild();
    View currentView = flipper.getCurrentView();

    // load the binary data
    showImage(currentView);

    // get the next to last view index (if keeping max. 3 images at a time in memory)
    int otherChild = (displayedChild - 2);
    if (otherChild < 0) {
        otherChild = otherChild + flipper.getChildCount();
    }

    // .. and remove it
    removeImage(flipper.getChildAt(otherChild));
}

private void showPreviousElement() {
    flipper.showPrevious();
    int displayedChild = flipper.getDisplayedChild();
    View currentView = flipper.getCurrentView();
    showImage(currentView);
    setTitle((CharSequence) currentView.getTag());
    int otherChild = (displayedChild + 2) % flipper.getChildCount();
    removeImage(flipper.getChildAt(otherChild));
}

private void removeImage(View view) {
    ImageView imageView = (ImageView) view.findViewById(R.id.gallery_image);
    if (imageView != null) {
        imageView.setImageResource(R.color.transparent);
        System.gc();
    }
}

private void showImage(View view) {
    ImageView imageView = (ImageView) view.findViewById(R.id.gallery_image);
    if (imageView != null) {
        bm = BitmapHelper.decodeByteArray(images.get(flipper.getDisplayedChild()).getImage().getBinaryObject());
        imageView.setImageBitmap(bm);
    }
}

为了进一步改进内存处理,我使用了我在 stackoverflow 上找到的 BitmapHelper 类中的一些代码,这有助于通过减小图像的大小来节省图像的内存。

关于android - HashMap反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5471262/

相关文章:

hashmap - 对包含引用的临时值强制执行生存期

java - HashMap 内部使用 Node<K, V> 数组,而 Hashtable 内部使用 Map.Entry<K, V> 数组,为什么会出现这种内部差异?

android - 即使应用程序关闭,也能保持持续的通知

android - 防止 Android 屏幕在 Activity 运行时变暗

java - 序列化和反序列化未实现 java.io.Serializable 的对象

javascript - 如何在没有 jQuery 的情况下序列化表单?

android - 外部图书馆规模

java - 从 C# WebService 生成的 JSON 字符串获取值

c# - 序列化。如何将多个列表序列化到一个文件中?

java - HashMap 元素的顺序是否可重现?