通过配置更改保留对象的静态模式

时间:2016-05-04 21:24:47

标签: java android static instance

我有足够的经验来了解配置更改。我知道如何保存和恢复ViewActivityFragment或其他任何内容的实例状态,我知道我们应该依赖它,而不是简单地使对象静态化。 / em>的

这个问题是关于字段static的问题。在"纯Java"将对象声明为static可以实现在实例之间共享对象。 在android系统中,当重新创建实例并清除其字段时,声明static字段也是让生存配置更改的快捷方式。

示例:

public class FooFragment extends Fragment {

    private static Object sObject;

    public void onViewCreated(View view, Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            sObject = new Object();
            sObject.toString();
        } else {
            sObject.toString();
        }
    }

}

在这种情况下,{<1}}可以在片段创建时初始化,只在片段重新创建时获取。当我们的类本身不是静态的,设计为基类,或者是sObject类时会出现问题。

abstract

现在,public abstract class BaseFragment extends Fragment { protected static Object sObject; } public class FooFragment extends BaseFragment { public void onViewCreated(View view, Bundle savedInstanceState) { if (savedInstanceState == null) { sObject = new Object(); sObject.toString(); } else { sObject.toString(); } } } public class BarFragment extends BaseFragment { public void onViewCreated(View view, Bundle savedInstanceState) { if (savedInstanceState == null) { sObject = new Object(); sObject.toString(); } else { sObject.toString(); } } } FooFragment都会访问(并且不可预测地使用)BarFragment的同一个实例。这是静止点,但不是我们想要的。我们希望sObjectFooFragment拥有他们自己的sObject ;我们只是希望它能够在配置变更和平台驱动的娱乐中幸存下来。

问题

如何为此目标设计基类?

这就是我想出来的,但我确信还有更好的东西。

BarFragment

基本上我保留一个静态地图,按子类名索引。

2 个答案:

答案 0 :(得分:1)

基本上,您正在实施全局缓存。您碰巧使用它进行配置更改这一事实只是一个细节。因此,您需要考虑全局缓存的标准内容。例如,考虑HashMap<String, WeakReference<Object>>,因此如果由于编码错误或未处理的异常导致无法从HashMap删除对象,则长期影响将是适度的。

就更多特定于Android的注意事项而言,进入该缓存的任何内容都不应该依赖于配置,例如从字符串资源中剔除的字符串的值。这些需要重建,因为配置更改可能会影响它们的价值。

此外,进入该缓存的任何内容都不应取决于预配置更改环境(例如前一个活动所拥有的视图),以帮助减少内存泄漏。

虽然您认为保留的片段不合适,但您可能会考虑查看其实现或其他全局缓存(例如,毕加索的图像缓存)的实现,以了解可能会影响您的其他想法。

答案 1 :(得分:0)

如果您有一个小应用,您的方法将有效。然而,有一些事情会让这很困难。

<强> 1。内存占用:即使您没有使用该屏幕,也会保留每个静态实例。如上所述,如果您的应用程序很小,这不是什么大问题,但如果您的应用程序增长,可能会导致问题。

<强> 2。可测试性:测试静态内容并不好玩:(

可能有更简单的方法来实现您的目标。

选项A 从DB加载。基本上保存尽可能少的状态(可能是您正在查看的数据ID)并在方向更改时加载数据。

选项B 使用IcePick等库可以更轻松地保存状态您可以保存基元,或为对象创建客户转换器(例如,使用GSON将对象转换为JSON)。