【问题标题】:load lot of images into titanium image view将大量图像加载到钛图像视图中
【发布时间】:2016-07-26 14:06:29
【问题描述】:

我正在将大量图像加载到钛图像视图中。问题是在android中我遇到了内存问题。这是我将图像放入图像视图的功能。在这个函数中,我正在调整图像的大小。

exports.SetImg = function(img, hightFactor, widthFactor, viewObj, deviceWidth, deviceHeight) {


    if (img != null && img != "") {
        var IMGhight = 0,
            IMGwidth = 0,
            height = 0,
            width = 0;

        var imgTemp = Ti.UI.createImageView({
            image : img
        });
        if (imgTemp != null) {

            if (imgTemp.toBlob().height != null && imgTemp.toBlob().width != null) {


                IMGhight = imgTemp.toBlob().height;
                IMGwidth = imgTemp.toBlob().width;
                height = alturaImg;
                width = larguraImg;

                if (height > deviceHeight * hightFactor) {
                    if (height > deviceHeight * hightFactor) {
                        height = deviceHeight * hightFactor;
                        width = (((deviceHeight * hightFactor) / IMGhight) * IMGwidth);
                    }

                    if (width < deviceWidth * widthFactor) {
                        width = deviceWidth * widthFactor;
                        height = (((deviceWidth * widthFactor) / IMGwidth) * IMGhight);
                    }
                } else if (width > deviceWidth * widthFactor) {
                    if (width > deviceWidth * widthFactor) {
                        width = deviceWidth * widthFactor;
                        height = (((deviceWidth * widthFactor) / IMGwidth) * IMGhight);
                    }

                    if (height < deviceHeight * hightFactor) {
                        height = deviceHeight * hightFactor;
                        width = (((deviceHeight * hightFactor) / IMGhight) * IMGwidth);
                    }
                } else if (height < deviceHeight * hightFactor) {
                    if (height < deviceHeight * hightFactor) {
                        height = deviceHeight * hightFactor;
                        width = (((deviceHeight * hightFactor) / IMGhight) * IMGwidth);
                    }

                    if (width < deviceWidth * widthFactor) {
                        height = deviceWidth * widthFactor;
                        height = (((deviceWidth * widthFactor) / IMGwidth) * IMGhight);
                    }
                } else if (width < deviceWidth * widthFactor) {
                    if (width < deviceWidth * widthFactor) {
                        width = deviceWidth * widthFactor;
                        height = (((deviceWidth * widthFactor) / IMGwidth) * IMGhight);
                    }
                    if (hight < deviceHeight * hightFactor) {
                        hight = deviceHeight * hightFactor;
                        width = (((deviceHeight * hightFactor) / IMGhight) * IMGwidth);
                    }
                }

                var imagem = Ti.UI.createImageView({
                    width : width,
                    height : hight,
                    image : img
                });

                viewObj.add(imagem);
                imagem = null;
                imgTemp = null;
                IMhight = null;
                IMGwidth = null;
                hight = null;
                width = null;
                img = null;
                hightFactor = null;
                widthFactor = null;
                viewObj = null;
                deviceWidth = null;
                deviceHeight = null;
            }
        }
    }
};

我已经为 GC 声明了所有变量为 null,但我仍然遇到内存问题。有人现在如何解决这个问题?

问题是我需要重复使用相同的图像来做其他事情,所以我需要它们来乞求。

【问题讨论】:

  • 虽然您正在调整图像的大小,但它的权重将完全相同。所以我认为你必须为你的应用找到某种延迟加载解决方案。
  • 大约 30 张图片,大小为 1024*800

标签: android memory-management titanium appcelerator


【解决方案1】:

imgTemp.toBlob() 提取到一个公共变量将对您的内存消耗产生巨大的积极影响。看看幕后发生了什么,您实际上每次调用toBlob() 时都会多次将图像加载到内存中!我在您的代码中看到了 4 个用法加上实际的图像视图使用,乘以 30 个图像,您已经得到了数百个位图副本。

更多证据请看这里的源代码 --

在 TiUIImageView.java 中: https://github.com/appcelerator/titanium_mobile/blob/e6a5f6c086a019dbdf810e225bb13c5c8d9115ac/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUIImageView.java#L945

在 TiBlob.java 中: https://github.com/appcelerator/titanium_mobile/blob/415bd6c66dcc55b1a59a59574f3babd3c3a84ede/android/titanium/src/java/org/appcelerator/titanium/TiBlob.java

【讨论】:

    【解决方案2】:

    您确实应该调整图像大小并将其保存为缩略图文件。而不仅仅是调整图像视图的大小并在其中显示整个图像。这样可以节省一些内存。

    另外,您正在创建多个 blob imgTemp.toBlob()。运行此命令一次并重用 blob 变量。所有其他计算都相同。它并不多,但只需计算一次并重复使用该值即可为您节省一些时间/空间。

    但是您需要调整图像的大小,也许使用自定义的 android 模块,如果您需要的话,该模块允许批量调整整个文件夹或文件数组的大小。

    【讨论】:

    • 我从服务器接收图像并从 URL 获取它们。创建图像阵列的最佳方法是什么?谢谢
    【解决方案3】:

    如果您从服务器接收图像,那么最好将调整大小的图像放在服务器上。服务器上图像的分辨率可以是您在应用中创建 ImageView 的最大宽度*高度。

    现在,如果您要在更大的 ImageView 中的某个其他屏幕上使用这些图像(例如全屏显示图像),那么您可以在服务器上为这两种情况使用不同的文件夹。例如

    • 对于较小的 ImageView,在服务器上创建一个 thumbnail 文件夹
    • 对于更大的 ImageView,创建另一个名为 pictures 的文件夹。
    • 现在,假设您在服务器上的实际图像是 my_image.jpg,大​​小宽度 = 1024,高度 = 800,然后放置 300*234 的缩略图,保持与此路径的纵横比相同 thumbnail/my_image.jpg 和此路径中的实际图像 pictures/my_image.jpg

    同样,如果你真的想根据自己的要求调整图像大小,那么Titanium Blob API like imageAsThumbnail 中有一些非常简洁的方法

    另外,如果你想一次加载 30 个 1024*800 的图像,那么你将不得不研究延迟加载方法,因为如果你一次创建 30 个 1024*800 的 ImageView,没有什么可以节省设备的内存。

    最后,如果您能提示我们您想要设计什么样的 UI,这样我们就可以建议您更好的方法来做这件事,而不仅仅是调整图像大小并对其执行许多计算,那就更好了。

    【讨论】:

    • 我已经更新了我的问题。我重新编写了钛文档,他们说延迟加载仅适用于 IOS,但我需要它用于 android
    • 您可以实现自己的延迟加载方式,因为可能有不止一种方式来实现。正如我所说,一个简单的模型或线框设计会更好地帮助我们更好地帮助您做您想做的事情。
    • 我在我需要创建的 UI 问题上放了一张图片
    • 如果像 Centro Culturul 这样的标签前面的 GREY-SQUARES 是您需要优化的 ImageView,那么我最好建议您降低服务器上图像的分辨率....因为此过程有两个好处:1 - 由于尺寸较小,您可以更快地获取图像。 (尝试将尺寸保持在 200x200 左右,因为我认为对于灰色方块中的图像就足够了。2 -缩小图像后,您的应用将使用足够的低内存。3 - 按照我使用缩略图方式的回答,您可以随时显示更大的图像。
    • 是的,灰色方块是图像位置。但我需要其他屏幕上的图像乞丐。但我想我找到了适用于这两种情况的尺寸。我的图像现在宽度为 700 像素,高度约为 400 像素,并且可以正常工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2011-02-17
    • 1970-01-01
    • 2013-07-29
    • 2019-09-22
    相关资源
    最近更新 更多