12

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

我的 Android 测试设备之一是 HTC One X。该设备以经常杀死后台应用程序而闻名(甚至包括启动器,最令人气愤的是),因为它在 RAM 分配方面往往处于边缘地位,可能是由于 HTC 膨胀软件。然而,就我的目的而言,这非常有用,因为它有助于突出各种低内存情况的影响,并允许我改进我的应用程序以应对此类事件。例如,我学到的一件事是,即使保留了 backstack,也可以杀死Application实例和其他资源。因此,为了提供良好的用户体验,即使单个进程运行应用程序,后台堆栈也可以保留,并且所有staticActivitystatic它持有,已经消失。出于这个原因,我的应用程序现在非常坚固,可以优雅地检查状态,并在必要时重新初始化它在恢复任何Activity.

继续我的具体问题,我看到了一个罕见的症状,通过代码检查,我相信只能由static一个类的成员被杀死然后重新初始化,而另一个静态资源在一个我的库类尚未重新初始化。我很欣赏两个独立资源之间的这种依赖关系static代表了我的糟糕设计,我将进行重构以避免这种情况。但是,我想知道我的分析是否可能是正确的——也就是说,是否有可能保留后台堆栈,但只有一些 static资源被杀死,特别是在每个库/包的基础上?

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

1 类是我们将调用的类Controller。它不用作 Singleton,但包含static Map在所有实例中通用的数据。它的初始化如下:

private static Map<String, String> sSomeMetaData;

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

接下来,我有一个名为MyFlyweightFactory. 这个类存在于一个单独的库中。这个类是一个单例:

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

罕见的问题情况似乎是Controllerfind的实例sSomeMetaData是空的,即使我知道它MyFlyweightFactory已经从它的Map. 我相信,这肯定只会发生,如果 的实例MyFlyweightFactory一直存在,因此不需要重新解析图像对象(这意味着它不会sSomeMetaData再次填充),但与此同时,static初始化器Controller已经再次执行。我可以确认sSomeMetaData没有在代码中的其他任何clear()地方编辑。

4

2 回答 2

3

你应该看看这个:活动生命周期。

在此处输入图像描述

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

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

这不是一个完整的应用程序,而是基于一个活动。所以它会开始扼杀它认为不那么重要的活动。在同一个应用程序中,某些活动可能会受到影响,而其他活动则不会。

请注意上表中的“Killable”列——对于那些标记为可终止的方法,在该方法返回后,托管该活动的进程可能随时被系统终止,而无需执行另一行代码。因此,您应该使用 onPause() 方法将任何持久性数据(例如用户编辑)写入存储。此外,方法 onSaveInstanceState(Bundle) 在将 Activity 置于这样的后台状态之前被调用,允许您将 Activity 中的任何动态实例状态保存到给定的 Bundle 中,以便稍后在 onCreate(Bundle) 中接收该 Activity需要重新创建。有关流程的生命周期如何与其托管的活动相关联的更多信息,请参阅流程生命周期部分。

于 2012-09-06T11:33:06.697 回答
1

我认为您在调试或跟踪应用程序中的问题时不知何故走错了路。

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

当您的应用程序Android因需要资源而被销毁时,您的Application类也将被“销毁/停止”并backstack保留。当您重新启动应用程序时,您的特定Application类将被“重新创建”(onCreate()将被调用),并且您的Activity后台堆栈也将被重新创建,这意味着Activity用户可见的最后一个类将被重新创建-创建。所以基本上,您的应用程序中发生的事情是预期的行为。为什么图书馆中的某些成员没有重新初始化......我想不通。

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

于 2012-09-06T12:06:02.203 回答