API 26 adds new option Bitmap.Config.HARDWARE
:
文档中未解释的问题:
Bitmap.Config.HARDWARE
而不是当速度是最高优先级和质量时的
Bitmap.Config.RGB_565
和可变性不是吗(例如,缩略图等)? 消耗任何堆内存并且仅驻留在GPU内存中?如果是这样,这似乎
最终缓解了
OutOfMemoryException
的顾虑处理图像。
从这个选项?
RGB_565解码?
如果使用此解码图像时我们超过了GPU内存,则会发生这种情况
选项?会抛出一些异常(也许是相同的
OutOfMemoryException
:)吗? 最佳答案
文档和公共(public)源代码尚未推送到Google's git。因此,我的研究仅基于部分信息,一些实验以及我自己将JVM移植到各种设备上的经验。
我的测试创建了一个大型可变位图,然后单击按钮将其复制到新的硬件位图中,然后将其添加到位图列表中。在崩溃之前,我设法创建了多个大位图实例。
我能够在android-o-preview-4 git push中找到它:
+struct AHardwareBuffer;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer);
+#else
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const struct AHardwareBuffer *buffer);
然后寻找documentation of AHardwareBuffer,并在Android共享内存(“ashmem”)中创建由
EGLClientBuffer
(本 map 形缓冲区)支持的ANativeWindowBuffer
。但是实际的实现可能会因硬件而异。关于这些问题:
对于SDK> = 26,
HARDWARE
配置可以通过避免每次将相同的位图返回到屏幕时将像素数据复制到GPU来改善低级位图的绘制。我猜它可以防止在将位图添加到屏幕时丢失某些帧。内存不计入您的应用程序,我的测试证实了这一点。
native 库文档说如果内存分配不成功,它将返回
null
。如果没有源代码,目前尚不清楚Java实现(API实现者)在这种情况下会做什么-它可能决定将
OutOfMemoryException
或fallback投向其他类型的分配。更新:实验表明没有抛出OutOfMemoryException。分配成功后-一切正常。分配失败后,模拟器崩溃(刚消失)。在其他情况下,在应用程序内存中分配位图时,我会收到奇怪的
NullPointerException
。由于不可预测的稳定性,我不建议在当前的生产环境中使用此新API。至少并非没有大量测试。
像素数据将在共享内存(可能是纹理内存)中,但是Java中仍然有一个小的
Bitmap
对象引用它(因此“ANY”是不准确的)。每个供应商都可以决定以不同的方式实现实际分配,这不是他们所绑定(bind)的公共(public)API。
因此
OutOfMemoryException
可能仍然是一个问题。我不确定如何正确处理它。HARDWARE
标志与质量无关,而与像素存储位置有关。由于配置标志不能为OR
编码,因此我假设将默认(ARGB_8888
)用于解码。(实际上,
HARDWARE
枚举对我来说似乎是一种hack)。HARDWARE
标志似乎与解码无关,因此与ARGB_8888
相同。内存快用完时,我的测试结果很糟糕。
模拟器有时会崩溃,而在其他情况下,我遇到了意外的无关的NPE。没有OutOfMemoryException发生,也没有办法告诉GPU内存何时耗尽,因此没有办法预见到这一点。