有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有足够的经验了解配置更改。我知道如何保存和恢复ViewActivityFragment或任何东西的实例状态,我知道我们应该依赖它,而不是简单地让对象保持静态

这个问题是关于场的static性的。在“纯Java”中,将对象声明为static的目的是在实例之间共享它。 在安卓系统中,声明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();
        }
    }

}

在这种情况下,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();
        }
    }
}

现在FooFragmentBarFragment将访问(并且不可预测地使用)同一个sObject实例。这是静态的要点,但不是我们想要的。我们希望FooFragmentBarFragment拥有自己的主题;我们只想让它在配置变化和平台驱动的娱乐中生存下来

问题:

我如何为这个目标设计基类

这就是我想到的,但我相信还有更好的办法

public abstract class BaseFragment extends Fragment {

    private static HashMap<String, Object> sObjects;

    public void onViewCreated(View view, Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            Object o = new Object();
            sObjects.put(getClass().getName(), o);
        }
    }

    protected final Object getObject() {
        return sObjects.get(getClass().getName());
    }
}

基本上,我保持一个静态映射,按子类名索引


共 (2) 个答案

  1. # 1 楼答案

    基本上,您正在实现一个全局缓存。您碰巧使用它来更改配置,这只是一个细节。因此,您需要考虑全局缓存的标准内容。例如,考虑^ {CD1}},因此,如果由于编码错误或未处理异常,未能从^ { CD2> }中移除对象,则长期影响将不大。p>

    就安卓系统而言,进入缓存的任何内容都不应该依赖于配置,比如从字符串资源中挑选的字符串的值。这些需要重建,因为配置更改可能会影响它们的价值

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

    虽然你认为保留的片段是不合适的,但是你可以考虑查看它们的实现,或者其他全局缓存(例如,Picasso的图像缓存)的实现,以了解其他可能出现在你身上的想法。p>
  2. # 2 楼答案

    如果你有一个小应用程序,你的方法就会奏效。然而,有几件事会让这件事变得困难

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

    2。可测试性:测试静态事物并不有趣:(

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

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

    选项B使用IcePick等库简化状态保存。您可以保存原语,或为对象创建客户转换器(例如,使用GSON将对象转换为JSON)