首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android,自定义视图中内存不足

Android,自定义视图中内存不足
EN

Stack Overflow用户
提问于 2011-01-27 14:05:50
回答 2查看 5.6K关注 0票数 1

我对一个应用程序进行了压力测试,该应用程序由许多自定义视图(实际上是3)组成,这些视图都保存在frameLayout中。

不过,一次只举行两次。我有视图1,添加视图2,动画1和动画在2,然后删除1,反之亦然,如果我通过视图。

然后,每个视图在使用以下方法创建图像数据时加载大量图像数据:

代码语言:javascript
复制
mBmp[background] = BitmapFactory.decodeStream(context.getAssets().open("view1_background.png"));

下面是我的视图切换代码的一个示例,这个切换向前切换到nextView。

代码语言:javascript
复制
currView.startAnimation(AnimClass.outToLeftAnimation(null));
    intView++;
    nextView = ViewFactory.getInstance(this, intView, viewInitializer);
    mainLayout.addView(nextView, 0);
    nextView.startAnimation(AnimClass.inFromRightAnimation(this));
    mainLayout.removeViewInLayout(currView);
    currView = nextView;
    nextView = null;

viewInitializer根据intView调用自定义视图并实例化它,然后使用上述方法加载图像。

问题是,如果我切换视图足够快,我就会导致它停止运行(即使我正在禁用按钮,直到幻灯片输出动画完成),在切换几次之后,我将丢失视图中的大多数图像,最后只剩下一两幅最小的图像。发生这种情况时,它不会显示任何错误,只显示以下消息(该视图中的每个图像一条):

代码语言:javascript
复制
01-27 13:52:00.730: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.011: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.011: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.011: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.093: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.128: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.144: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.179: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.245: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.261: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.277: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.343: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.363: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.409: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.429: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.511: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264

如果我切换视图,它在每个视图上都会这样做。在我看来,我的视图切换代码并不是在视图被删除或删除时释放视图,或者视图被删除后图像(位图)不会被释放。

如果我使用了返回我的主要活动的意图,我会得到以下信息:

代码语言:javascript
复制
Surface  E  Surface (identity=4810) requestBuffer(0, 00000033) returneda buffer with a null handle
Surface  E  getBufferLocked(0, 00000033) failed (Out of memory)
Surface  E  dequeueBuffer failed (Out of memory)
ViewRoot  E  OutOfResourcesException locking surface
ViewRoot  E  android.view.Surface$OutOfResourcesException
ViewRoot  E     at android.view.Surface.lockCanvasNative(Native Method)
ViewRoot  E     at android.view.Surface.lockCanvas(Surface.java:314)
ViewRoot  E     at android.view.ViewRoot.draw(ViewRoot.java:1363)
ViewRoot  E     at android.view.ViewRoot.performTraversals(ViewRoot.java:1172)
ViewRoot  E     at android.view.ViewRoot.handleMessage(ViewRoot.java:1749)
ViewRoot  E     at android.os.Handler.dispatchMessage(Handler.java:99)
ViewRoot  E     at android.os.Looper.loop(Looper.java:123)
ViewRoot  E     at android.app.ActivityThread.main(ActivityThread.java:4627)
ViewRoot  E     at java.lang.reflect.Method.invokeNative(Native Method)
ViewRoot  E     at java.lang.reflect.Method.invoke(Method.java:521)
ViewRoot  E     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
ViewRoot  E     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
ViewRoot  E     at dalvik.system.NativeStart.main(Native Method)

有人能告诉我哪里出了问题吗?

编辑:没有找到确切的原因,但我通过在切换视图之间执行垃圾收集来解决问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-20 23:08:32

您是否考虑过使用位图选项来导入占用较少图像数据的较小图像?如果你有高分辨率的图像(如。相机照片)从来没有必要向用户展示完整的图像分辨率。

在导入位图之前尝试这样做。

代码语言:javascript
复制
Options options = new Options();            
options.inJustDecodeBounds = true;

BitmapFactory.decodeFile(context.getAssets().open("view1_background.png"), options);

options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

Log.i(getClass().getSimpleName(), 
            "height: " + options.outHeight +
            "\nwidth: " + options.outWidth +
            "\nmimetype: " + options.outMimeType +
            "\nsample size: " + options.inSampleSize);

options.inJustDecodeBounds = false;

mBmp[background] = BitmapFactory.decodeStream(context.getAssets().open("view1_background.png"));

其中样本大小由下列因素决定:

代码语言:javascript
复制
public static int calculateInSampleSize( Options options, int reqWidth, int reqHeight) 
{
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    while (height / inSampleSize > reqHeight || width / inSampleSize > reqWidth) 
    {
        if (height > width)
        {
            inSampleSize = height / reqHeight;
            if (((double)height % (double)reqHeight) != 0) 
            {
                inSampleSize++;
            }
        } 
        else 
        {
            inSampleSize = width / reqWidth;
            if (((double)width % (double)reqWidth) != 0) 
            {
                inSampleSize++;
            }
        }
    }
    return inSampleSize;
}
票数 0
EN

Stack Overflow用户

发布于 2011-01-28 09:59:59

我喜欢在处理很多图像的时候做些“清理”.在从布局中删除视图之前,您是否尝试过去初始化(回收位图)所加载的图像?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4817306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档