我想在一个活动中实现onTrimMemory(int level)
,在内存中写一些Bitmap
对象到硬盘驱动器,并回收它们。但我不确定这是否会阻止UI线程,我应该在另一个线程中运行代码吗?或者默认情况下该方法已经在另一个线程上运行了?
另一个相关的问题是:当活动在前台时,onTrimMemory
会被调用吗?医生说:
换句话说,如果我正确实现onTrimMemory
(释放足够的内存),我是否需要担心OOM错误?
或者onTrimMemory
仅在活动进入后台时被调用,因此当应用程序位于前台时,OOM仍然可以发生?
1.在UI线程上调用onTrimMemory
吗?
是。来自docs:
...响应系统回调的方法(例如onKeyDown()报告用户操作或生命周期回调方法)总是在进程的UI线程中运行。
如果您想从源代码中得到保证,请注意调用的根源是here;一个Runnable
张贴到ActivityThread's
主要Handler
。
2.当活动在前台时,onTrimMemory
会被调用吗?
我不确定。文档没有明确禁止它,因此精心设计的应用程序应该允许这种可能性。
看起来源代码中的this call可能会应用于前台应用程序。
3.如果我正确实现onTrimMemory
(释放足够的内存),我是否需要担心OOM错误?
您总是需要担心OOM错误。始终可以请求大于系统可提供的分配。 onTrimMemory()
计划反映了一种在“尽力而为”的基础上释放资源的方法;无法保证您的应用或系统上的其他人能够合作达到任何特定的内存阈值。
如果你的应用程序在后台,它可能不会做太多,特别是在分配方式。也许是你的设备上的其他应用程序获得你应该担心的OOM(如果你的应用程序无法释放“足够的”内存以响应onTrimMemory()
调用)。
4.或者onTrimMemory
仅在活动进入后台时被调用,因此当应用程序位于前台时,OOM仍然可以发生?
如上所述,OOM可以在您尝试进行分配时发生。希望您设备上的其他应用程序能够真诚地努力减少内存消耗(在onTrimMemory()
之后),以便为您的前台应用程序提供最大量的资源。如果他们不这样做,他们可能会被终止(正如您可以从ActivityManagerService.java中的逻辑中看到的那样),从而释放更多资源。
系统将尽最大努力确保您的前台应用程序具有其请求的资源。也就是说,您应该以合理的方式规划内存使用情况,并在发生错误(OOM)时能够正常恢复。