java静态模式通过配置更改保留对象
我有足够的经验了解配置更改。我知道如何保存和恢复View
、Activity
、Fragment
或任何东西的实例状态,我知道我们应该依赖它,而不是简单地让对象保持静态
这个问题是关于场的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();
}
}
}
现在FooFragment
和BarFragment
将访问(并且不可预测地使用)同一个sObject
实例。这是静态的要点,但不是我们想要的。我们希望FooFragment
和BarFragment
拥有自己的主题;我们只想让它在配置变化和平台驱动的娱乐中生存下来
问题:
我如何为这个目标设计基类
这就是我想到的,但我相信还有更好的办法
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());
}
}
基本上,我保持一个静态映射,按子类名索引
# 1 楼答案
基本上,您正在实现一个全局缓存。您碰巧使用它来更改配置,这只是一个细节。因此,您需要考虑全局缓存的标准内容。例如,考虑^ {CD1}},因此,如果由于编码错误或未处理异常,未能从^ { CD2> }中移除对象,则长期影响将不大。p>
就安卓系统而言,进入缓存的任何内容都不应该依赖于配置,比如从字符串资源中挑选的字符串的值。这些需要重建,因为配置更改可能会影响它们的价值
此外,进入该缓存的任何内容都不应依赖于预配置更改环境,例如前一个活动拥有的视图,以帮助减少内存泄漏
虽然你认为保留的片段是不合适的,但是你可以考虑查看它们的实现,或者其他全局缓存(例如,Picasso的图像缓存)的实现,以了解其他可能出现在你身上的想法。p># 2 楼答案
如果你有一个小应用程序,你的方法就会奏效。然而,有几件事会让这件事变得困难
1。内存占用:即使不使用该屏幕,也会保留每个静态实例。如上所述,如果应用程序很小,这不是什么大问题,但如果应用程序增长,可能会导致问题
2。可测试性:测试静态事物并不有趣:(
可能有更简单的方法来实现你的目标
选项A从DB加载。基本上尽可能少地保存状态(可能是您正在查看的数据的ID),并在方向更改时加载数据
选项B使用IcePick等库简化状态保存。您可以保存原语,或为对象创建客户转换器(例如,使用GSON将对象转换为JSON)