`onTrimMemory` 是否在 UI 线程上被调用?

Does `onTrimMemory` get called on UI thread or not?

我想在一个activity中实现onTrimMemory(int level),将内存中的一些Bitmap对象写入硬盘,并回收。但是我不确定这是否会阻塞 UI 线程,我应该 运行 另一个线程中的代码吗?或者默认情况下该方法已经 运行 在另一个线程上?

另一个相关问题是:当 activity 在前台时,是否会调用 onTrimMemory?医生说:

This will happen for example when it goes in the background and there is not enough memory to keep as many background processes running as desired.

换句话说,如果我正确地实现onTrimMemory(释放足够的内存),我还需要担心OOM错误吗?

或者onTrimMemory只有在activity进入后台时才会被调用,所以应用程序在前台时仍然会发生OOM?

1. onTrimMemory 是否在 UI 线程上被调用?

是的。来自 docs:

...methods that respond to system callbacks (such as onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the process.

如果您想从源代码中得到保证,请注意发生调用的根 hereRunnable 发布到 ActivityThread'sHandler.

2。 onTrimMemory 是否在 activity 位于前台时被调用?

我不确定。文档没有明确禁止它,所以一个设计良好的应用程序应该允许这种可能性。

看起来源代码中的 this call 可能适用于前台应用程序。

3。如果我正确实现onTrimMemory(释放足够的内存),我需要担心OOM错误吗?

你总是需要担心OOM错误。总是可以请求比系统可以提供的更大的分配。 onTrimMemory() 方案反映了一种在 "best effort" 基础上释放资源的方法;无法保证您的应用程序或系统上的其他应用程序会合作达到任何特定的内存阈值。

如果您的应用程序在后台,它可能不会做太多事情,尤其是在分配方式方面。也许是您设备上的 other 应用程序出现 OOM,您应该担心(如果您的应用程序未能释放 "enough" 内存以响应 onTrimMemory() 调用).

4.或者 onTrimMemory 只在 activity 进入后台时被调用,所以应用程序在前台时仍然会发生 OOM?

如前所述,OOM 可能会在您尝试进行分配时发生。希望您设备上的其他应用程序会做出善意的努力来减少它们的内存消耗(在 onTrimMemory() 之后),以便为您的前台应用程序提供最大数量的资源。如果不这样做,它们很可能会被终止(从 ActivityManagerService.java 中的逻辑可以看出),这会释放更多资源。

系统将尽最大努力确保您的前台应用程序拥有它所请求的资源。也就是说,您应该以合理的方式规划您的内存使用,并能够在发生错误 (OOM) 时从容恢复。