我将使用基于SoftReference的缓存(一个非常简单的事情).但是,我在为它编写测试时遇到了一个问题.
测试的目的是检查缓存是否在内存清理发生后再次从服务器请求先前缓存的对象.
在这里,我找到了如何使系统释放软引用对象的问题.调用System.gc()是不够的,因为在内存不足之前不会释放软引用.我正在PC上运行此单元测试,因此VM的内存预算可能非常大.
==================后来添加==============================
谢谢所有照顾的人!
考虑到所有职业选手和反对者后,我决定按照nanda和jarnbjo的建议采取蛮力方式.然而,似乎JVM并不是那么愚蠢 - 如果你要求一个比VM的内存预算更大的块,它甚至都不会尝试垃圾收集.所以我修改了这样的代码:
/* Force releasing SoftReferences */
try {
final List<long[]> memhog = new LinkedList<long[]>();
while(true) {
memhog.add(new long[102400]);
}
}
catch(final OutOfMemoryError e) {
/* At this point all SoftReferences have been released - GUARANTEED. */
}
/* continue the test here */
Run Code Online (Sandbox Code Playgroud) 我的应用程序中有一个图像缓存,它使用SoftReferences实现.Dalvik以相对较小的堆启动应用程序,然后在需求的情况下增加它.但我想从一开始就让我的堆大小更大.这是因为当我已经在缓存中有一些图像,并且活动开始(例如)或其他峰值内存需求发生时,我的缓存被清除,以便为该峰值需求提供内存.结果,在峰值消失后,我仍然有2-3 MB的可用空间,但我的缓存是空的!
我看到这个问题的解决方案是预先分配一个更大的正式堆,所以即使峰值消耗为2-3 MB,它仍然有一些空间,所以我的SoftReferences不会被清除.
我发现这VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE)会有所帮助.尤其是,谷歌使用,在他们的应用程序,如提到这里.但是,VMRuntime类已标记为已弃用,并且在将来的版本中表示将从公共API中删除.所以setMinimumHeapSize不是一个永久的解决方案.
然后我如何让Dalvik在启动时增加我的堆?
目前,我通过分配一个大型数组并释放它来使用一种非常简单和俗气的技术.这使得Dalvik成长为我想要的堆.但是,我确信必须有更优雅的方式.你能告诉我吗?
它接收Dalvik的垃圾收集器不尊重SoftReferences并尽快删除它们,就像WeakReferences一样.我还不是100%肯定,但是在我看到LogCat中的"GC释放bla-bla-bla字节"之后,我的SoftReferences仍然被释放了大约3MB的可用内存.
另外,我看到马克·墨菲评论这里:
除非它在Android上不起作用,至少在1.5时间范围内.我不知道GC SoftReference错误是否已修复.SoftReferences很快就会遇到这个bug.
这是真的吗?SoftReferences不受尊重吗?
如何解决这个问题?
假设应用程序已经有一堆活动,然后使用FLAG_ACTIVITY_NEW_TASK从应用程序上下文启动一个新活动.这发生在同一个进程中,即在应用程序内部,如下所示:
AppContext -> A(FLAG_ACTIVITY_NEW_TASK) -> B -> C; AppContext -> D(FLAG_ACTIVITY_NEW_TASK)
Run Code Online (Sandbox Code Playgroud)
根据文档,我们现在有2个任务:
Task 1: A, B, C; Task 2: D
Run Code Online (Sandbox Code Playgroud)
从文档中可以看出,用户理论上可以独立地切换到活动C或活动D,因为它们属于不同的任务.然而,在实践中,我无法切换到活动C - 它总是切换到D.
我的问题是: 如果在与FLAG_ACTIVITY_NEW_TASK相同的过程中启动,任务是不是独立的,用户只能切换到最顶层任务中的最顶层活动?
如果答案是"否",那么用户切换到任务1的方式是什么?
答案是:否
任务是独立的,用户可以独立切换他们的活动,有效地将您的应用程序的两个活动放在堆栈顶部.在询问原始问题三年后,我刚刚找到了用例.
我们的应用程序将自己注册为URL方案的处理程序(如market://xxx.yyy/zzz).现在让我们想象一下,用户使用启动器启动了应用程序,进入某事物(活动A, B, C)的中间,然后离开了.然后在浏览器中,用户单击URL以启动我们的其他活动(活动D).这导致在同一时间有两个任务:活动A, B, C(C在顶部)和活动D.用户可以通过任务历史在这两个活动之间切换.
有趣的是,使用应用程序自己的图标在任务历史记录中可以看到活动C,但是使用浏览器的图标可以看到活动D. 无论如何,两者都可以切换到.
此外,这两个任务A-B-C,并D在同一个进程中运行.这意味着所有单重对象和静态数据都在它们之间共享.因此,如果不采取谨慎措施,他们可能会破坏彼此的状态.
Android 似乎没有提供这样一个有用的小部件。但是,我的屏幕设计需要这样的视图:

此外,交互设计要求根据其他数据显示和隐藏此类框。
当然,我可以从我的 XML 布局中的单独元素构建这样的框(例如,从一个形状和一个文本视图),但是管理它们的可见性变成了地狱......
所以很明显,这里需要的是一个容器,就像一个相对布局。这样的容器可以在 XML 布局中有子项,并且可以通过简单的 setVisibility(...) 调用显示和隐藏。
有人可以给我一个提示如何做到这一点吗?