将大量图像加载到钛图像视图中

时间:2016-07-26 14:06:29

标签: android memory-management titanium appcelerator

我正在将大量图像加载到钛金属的图像视图中。问题是在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但我仍然遇到了内存问题。现在有人如何解决这个问题?

This is the layout that I need do make.

问题是我需要将相同的图像重复用于其他东西,所以我需要它们来乞求。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

您应该真正调整图像大小并将其保存到缩略图文件中。而且不仅要调整imageview的大小并在其中显示整个图像。那会省你一些记忆。

您还要创建多个blob imgTemp.toBlob()。运行此命令一次并重用blob变量。所有其他计算都是一样的。当你只计算一次并重复使用它时,它并不会节省你一些时间/空间。

但你需要调整图像的大小,可能还有一个自定义的android模块,允许批量调整整个文件夹或文件数组,如果你需要的话。

答案 2 :(得分:0)

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

现在,如果您要在较大的ImageView中的其他屏幕上使用这些图像(比如以全屏显示图像),那么您可以在服务器上为这两种方案使用不同的文件夹。 e.g。

  • 对于较小的ImageView,请在服务器
  • 处创建缩略图文件夹
  • 对于较大的ImageView,创建另一个名为图片的文件夹。
  • 现在,假设您在服务器上的实际图像是 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,则无法保存设备的内存。

最后,如果你能暗示我们想要设计什么样的用户界面会更好,这样我们就可以建议你更好的方法来做到这一点,而不仅仅是调整图像大小并对它们进行大量的计算。