当静态资源被杀死时,它们是否全部被杀死,或者有些遗留在罕见的边缘情况中?

时间:2012-09-06 11:21:37

标签: java android

注意:虽然到目前为止(9月6日)提供的两个答案很有意思,但遗憾的是它们没有解决这个问题。

我的一个Android测试设备是HTC One X.这个设备以频繁杀死后台应用程序(甚至包括启动器,最令人愤怒)而闻名,因为它在RAM分配方面往往生活在边缘,可能是由于HTC英国媒体报道但是,就我的目的而言,这非常有用,因为它有助于强调各种低内存情况的影响,并允许我改进我的应用程序以应对此类事件。例如,我学到的一件事是,即使保留Application后台堆栈,也可以杀死static实例和其他Activity资源。因此,为了提供良好的用户体验,即使运行应用程序的单个进程以及它所拥有的所有static已经消失,也可以保留backstack。出于这个原因,我的应用程序现在非常坚固,在优雅地检查状态,并在必要时对重新初始化进行操作,恢复任何Activity所需的“Singleton”数据。

为了解决我的具体问题,我一直看到一种罕见的症状,通过代码检查,我认为只能由一个类的static成员被杀,然后重新初始化,而我的某个库类中的另一个静态资源已经 not 重新初始化。我理解两个独立的static资源之间的这种依赖性代表了我的不良设计,我将重构以避免这种情况。但是,我想知道我的分析是否可能是正确的 - 也就是说,是否可以在保留后台堆栈的情况下使用,但只有某些 static资源是特别是在每个图书馆/包装的基础上被杀?

编辑1 我会提供有关这两个类的更多信息。

第1课是我们称之为Controller的课程。 用作Singleton,但包含static Map个数据,这些数据在所有实例中都是通用的。它的初始化如下:

private static Map<String, String> sSomeMetaData;

static {
    sSomeMetaData = new HashMap<String, String>();
}

接下来,我有一个名为MyFlyweightFactory的课程。该课程位于单独的库中。这个类是Singleton:

private static MyFlyweightFactory instance = new MyFlyweightFactory();

public static synchronized MyFlyweightFactory getInstance(){
    return instance;
}   

private MyFlyweightFactory(){ }

TreeMap<String, MyParserRenderer> images = new TreeMap<String, MyParserRenderer>(); 

现在,这是依赖项。工厂类有一个getter方法来获取某个命名的图像对象,该对象是通过解析文件系统中的文件而构造的。如果工厂初始化后没有要求工厂提供该图像,它会从文件中解析它(它实际上是我的SVG图像解析器库)。图像被解析为MyParserRenderer对象。当此图像解析发生时,工厂还会在Controller类“sSomeMetaData成员中填充一些数据。工厂保留的所有图像都保存在您上面看到的images成员TreeMap中。因此,这些图像是static Singleton工厂实例的非静态成员。

罕见的问题情况似乎是Controller的实例发现sSomeMetaData为空,即使我知道MyFlyweightFactory已经从其Map提供了一些对象。我相信,如果MyFlyweightFactory的内容保持不变,因此无需重新解析图像对象(这意味着填充{ {1}}再一次),但与此同时,sSomeMetaData的{​​{1}}初始化程序再次执行。我可以确认static 在代码中的任何其他位置Controller

2 个答案:

答案 0 :(得分:3)

你应该看看这个:Activity lifecycle.

enter image description here

当你内存不足时,暂停的活动将被释放以释放内存。

因此,为什么你应该在必须重新创建活动的每种情况下尝试解释这一点。

这不是一个完整的应用程序,而是基于活动。因此它将开始杀死它认为不那么重要的活动。某些活动可能会受到影响,有些活动可能会受到影响。

  

请注意上表中的“Killable”列 - 对于那些标记为可填充的方法,在该方法返回后,托管该活动的进程可能会在任何时候被系统杀死,而不会执行其代码的另一行。因此,您应该使用onPause()方法将任何持久性数据(例如用户编辑)写入存储。此外,在将活动置于这样的背景状态之前调用onSaveInstanceState(Bundle)方法,允许您将活动中的任何动态实例状态保存到给定的Bundle中,以便稍后在onCreate(Bundle)中接收需要重新创建。有关流程生命周期如何与其托管的活动相关联的详细信息,请参阅流程生命周期部分。请注意,将持久数据保存在onPause()而不是onSaveInstanceState(Bundle)中非常重要,因为后者不是生命周期回调的一部分,因此不会在其文档中描述的所有情况下调用。

答案 1 :(得分:1)

我认为您在调试或跟踪应用程序中的问题时,在某种程度上是错误的。

以下是我可以告诉你的内容,以及我认为你理解错误的内容:

当您的应用程序被Android销毁,因为它需要资源时,您的Application课程也将被销毁/停止&#34;并保留backstack。当您重新启动应用程序时,系统会重新创建您的特定Application课程&#39; (onCreate()将被调用),您的Activity后台堆栈也将被重新创建,这意味着将重新创建用户可见的最后Activity。所以基本上,你的应用程序中发生的是预期的行为。为什么图书馆的某些成员不能重新初始化......我无法弄明白。

我在这里也有类似的问题:Application restart - Activity Entry Point