【问题标题】:Throwing OutOfMemoryError on create Bitmap在创建位图时抛出 OutOfMemoryError
【发布时间】:2018-12-17 09:40:21
【问题描述】:

我有一台带有 LCD 屏幕的定制 Android 设备。它可以绘制位图。我从 Android 视图中准备它们。

private Bitmap loadBitmapFromView() {
    if ((mView.getVisibility() != VISIBLE) ||
            (mView.getMeasuredWidth() <= 0) ||
            (mView.getMeasuredHeight() <= 0)) return null;
    Bitmap b;
    if ((mView instanceof ImageView) && !(mView instanceof ImageButton)) {
        BitmapDrawable drawable = ((BitmapDrawable) ((ImageView) mView).getDrawable());
        if (drawable == null) return null;
        b = Bitmap.createScaledBitmap(drawable.getBitmap().copy(drawable.getBitmap().getConfig(), true),
                mView.getMeasuredWidth(), mView.getMeasuredHeight(), false);
    } else {
        b = Bitmap.createBitmap(mView.getMeasuredWidth(), mView.getMeasuredHeight(), ARGB_8888);
    }
    replaceColor(b, ColorChannel.ALPHA, 0, mBackgroundColor);
    Canvas c = new Canvas(b);
    mView.layout(mLocation.x - mParentLocation.x, mLocation.y - mParentLocation.y,
            mLocation.x - mParentLocation.x + mView.getMeasuredWidth(),
            mLocation.y - mParentLocation.y + mView.getMeasuredHeight());
    mView.draw(c);
    return b;
}

此处使用 ARGB_8888 是因为某些视图具有透明度。

使用一段时间后停止绘制。

我在 Manifest 中添加了 android:largeHeap="true"android:hardwareAccelerated="false" 并得到了 OOM

12-17 11:19:32.591 15169-15169/com.appcard.androidterminal E/art: Throwing OutOfMemoryError "Failed to allocate a 614412 byte allocation with 4194304 free bytes and 244MB until OOM"
12-17 11:19:32.619 15169-15169/com.appcard.androidterminal E/Surface: dequeueBuffer failed (Function not implemented)
12-17 11:19:32.620 15169-15169/com.appcard.androidterminal E/ViewRootImpl: Could not lock surface
    java.lang.IllegalArgumentException
        at android.view.Surface.nativeLockCanvas(Native Method)
        at android.view.Surface.lockCanvas(Surface.java:264)
        at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2998)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2966)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2753)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2367)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1292)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6598)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
        at android.view.Choreographer.doCallbacks(Choreographer.java:603)
        at android.view.Choreographer.doFrame(Choreographer.java:572)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
        at android.os.Handler.handleCallback(Handler.java:815)
        at android.os.Handler.dispatchMessage(Handler.java:104)
        at android.os.Looper.loop(Looper.java:194)
        at android.app.ActivityThread.main(ActivityThread.java:5643)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

我尝试在绘制后回收位图,但没有帮助。

【问题讨论】:

    标签: android bitmap out-of-memory


    【解决方案1】:

    这是因为内存限制。您可以加载按比例缩小的位图版本。

    按照此处的文档了解有关如何有效加载位图的更多信息

    https://developer.android.com/topic/performance/graphics/load-bitmap

    【讨论】:

    • 在此示例中,它们缩放从资源中获取的位图。在我的情况下,如何缩小从视图中获取的位图?
    【解决方案2】:

    我通过用 Glide 替换 imageView.setImageBitmap(bitmap)imageView.setImageResource(imageRes) 解决了 OutOfMemory 问题: https://bumptech.github.io/glide/doc/targets.html

    【讨论】:

    • 我没有将位图加载到图像视图中。之后我需要它在单独的 LCD 屏幕上绘图。
    【解决方案3】:

    尝试使用

    Bitmap bitmap = Bitmap.createScaledBitmap(view.getDrawingCache(), width, height, false);
    

    这里的view是你要绘制的view,width和height是输出的宽高。

    如果问题仍然存在,您可以将位图的大小减小 2 倍左右。其次,如果你在处理多个位图,你可以一个一个地做,这样内存中只有一两个位图是真正需要的。

    【讨论】:

    • 仍在抛出 OOM。还有什么想法吗?
    • 将宽度和高度进一步减小一个因子 width = width/2。也检查应用程序的其他部分
    猜你喜欢
    • 2014-12-31
    • 1970-01-01
    • 2014-08-13
    • 2017-10-28
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多