相关疑难解决方法(0)

如何在使用大图像时使用JNI位图操作来帮助避免OOM?

背景

大多数时候,在Android上获取OOM是由于使用了太多位图和/或创建大位图.

最近我决定试用JNI,以便通过将数据本身存储在JNI端来避免OOM.

在与JNI搞砸了一段时间后,我在SO上创建了一些帖子,寻求帮助并分享我的知识,现在我决定与你分享更多代码.如果有人有兴趣阅读调查结果或做出贡献,这里有帖子:

这一次,我添加了存储,恢复,裁剪和旋转位图的功能.它应该很容易添加更多选项,如果其他人在这里将自己的代码添加到更有用的功能,我会很高兴.

所以我要展示的代码实际上是合并了我创造的所有东西.

示例使用代码:

Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
final int width=bitmap.getWidth(),height=bitmap.getHeight();
// store the bitmap in the JNI "world"
final JniBitmapHolder bitmapHolder=new JniBitmapHolder(bitmap);
// no need for the bitmap on the java "world", since the operations are done on the JNI "world"
bitmap.recycle();
// crop a center square from the bitmap, from (0.25,0.25) to (0.75,0.75) of the bitmap.
bitmapHolder.cropBitmap(width/4,height/4,width*3/4,height*3/4);
//rotate the bitmap:
bitmapHolder.rotateBitmapCcw90();
//get the output java bitmap , …
Run Code Online (Sandbox Code Playgroud)

java-native-interface android bitmap out-of-memory android-ndk

46
推荐指数
1
解决办法
3万
查看次数

如何将位图缓存到本机内存中

对于我的10,000点,我决定用这个很酷的网站来点缀一些东西:一种在本机内存上缓存位图的机制.

背景

Android设备的每个应用程序的内存量非常有限 - 堆的范围从16MB到128MB,具体取决于各种参数.

如果您通过此限制,则会获得OOM,当您使用位图时,这可能会发生多次.

很多时候,应用程序可能需要克服这些限制,对巨大的位图执行繁重的操作,或者只是存储它们以供以后使用,并且您需要

我想出的是一个简单的java类,它可以使事情变得更容易.

它使用JNI来存储位图数据,并能够在需要时恢复它.

为了支持该类的多个实例,我必须使用我发现的技巧(这里).

重要笔记

  • 数据仍然存储在RAM中,因此如果设备没有足够的RAM,应用程序可能会被杀死.

  • 记得尽快释放记忆.它不仅可以避免内存泄漏,而且还可以避免在您的应用程序到达后台时首先被系统优先处理.

  • 如果您不想忘记释放内存,可以在每次还原位图时释放它,或者使类实现Closable.

  • 作为一种安全措施,我已经使它在finalize()方法中自动释放其本机内存,但不要让它负责这项工作.风险太大了.当这样的事情发生时,我也写了它写入日志.

  • 它的工作方式是将整个数据复制到JNI对象中,为了还原,它从头开始创建位图并将数据放入其中.

  • 正在使用和恢复的位图采用ARGB_8888格式.当然,您可以将其更改为您想要的任何内容,只是不要忘记更改代码...

  • 大位图可能需要一些时间来存储和恢复,因此在后台线程上执行它可能是明智的.

  • 这不是一个完整的OOM解决方案,但它可能有所帮助.例如,您可以将它与您自己的LruCache结合使用,同时避免将堆内存用于缓存本身.

  • 代码仅用于存储和恢复.如果您需要执行某些操作,则需要进行一些研究.openCV可能就是答案,但是如果你想要执行一些基本的东西,你可以自己实现它们(这里是使用JNI旋转大图像的例子).如果你知道其他选择,请在这里告诉我.

希望这对某些人有用.请写下你的意见.

此外,如果您发现代码有任何问题或建议填补,请告知我们.


好的解决方案

如果您希望在JNI端执行更多操作,您可以使用我所做的这篇文章.它基于我在这里编写的代码,但允许您进行更多操作,您可以轻松添加更多自己的代码.

java-native-interface android caching native bitmap

38
推荐指数
1
解决办法
2万
查看次数

最大缓存大小

我打算将打开的文件保存到android缓存中.但在开始之前,我想知道缓存文件的最大大小,以及如何根据设备管理缓存大小?

android

13
推荐指数
1
解决办法
1万
查看次数

Android:GC不尊重SoftReferences?

它接收Dalvik的垃圾收集器不尊重SoftReferences并尽快删除它们,就像WeakReferences一样.我还不是100%肯定,但是在我看到LogCat中的"GC释放bla-bla-bla字节"之后,我的SoftReferences仍然被释放了大约3MB的可用内存.

另外,我看到马克·墨菲评论这里:

除非它在Android上不起作用,至少在1.5时间范围内.我不知道GC SoftReference错误是否已修复.SoftReferences很快就会遇到这个bug.

这是真的吗?SoftReferences不受尊重吗?

如何解决这个问题?

android garbage-collection weak-references soft-references

10
推荐指数
1
解决办法
1903
查看次数

在Android应用程序中设置最小堆大小的目的是什么?

在Android操作系统的Google日历应用中,您将在CalendarActivity的onCreate方法中遇到此行.

// Eliminate extra GCs during startup by setting the initial heap size to 4MB.
VMRuntime.getRuntime().setMinimumHeapSize(INITIAL_HEAP_SIZE)
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么设置为4MB会消除GC吗?

java mobile android

7
推荐指数
1
解决办法
4939
查看次数

声音剪辑会出现堆大小溢出问题

我正在创建一个涉及多个短声道剪辑的Android应用.目前,我正在使用SoundPool菜单活动开始第二次活动时加载我的声音片段.我似乎遇到的问题是,一旦这个辅助活动开始,声音片段的加载会导致多个堆大小溢出,然后在一点之后活动实际加载(模拟器从不给出错误或强制退出).MediaPlayer在这里使用帮助我并保持这些堆大小溢出?

此外,此时,菜单活动开始等待结果的第二个活动(使用该startActivityForResult()功能).这是否意味着菜单活动被保存在内存中以及将第二个活动加载到内存中?如果是这样,我可以通过finish()在第二个菜单活动启动后调用菜单活动来帮助解决我的内存问题(当用户希望返回菜单时重新启动菜单活动,或者这会引发一系列全新的问题吗?) ?

android memory-management soundpool

4
推荐指数
1
解决办法
5393
查看次数