In a Fragment
使用 UI 通常可以节省一些View
s 作为实例状态以加速访问。例如,链接到您的EditText
所以你不必findViewById
一直都是这样。
问题是一个View
保留对Activity
语境。现在,如果您保留View
您还保留对该上下文的引用。
如果上下文仍然有效,但典型的保留情况是重新启动活动,那么这没有问题。例如,经常用于屏幕旋转。活动重新创建将创建一个新的上下文,而旧的上下文将被垃圾收集。但它现在不能被垃圾收集,因为你Fragment
仍然有对旧版本的引用。
下面的例子展示了如何不这样做
public class LeakyFragment extends Fragment {
private View mLeak; // retained
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mLeak = inflater.inflate(R.layout.whatever, container, false);
return mLeak;
}
@Override
public void onDestroyView() {
super.onDestroyView();
// not cleaning up.
}
}
要解决这个问题,您需要清除对 UI 的所有引用onDestroyView
。一旦Fragment
实例被重新使用,您将被要求创建一个新的 UIonCreateView
。之后保留 UI 也没有意义onDestroyView
。不会使用 Ui。
本例中的修复只是改变onDestroyView
to
@Override
public void onDestroyView() {
super.onDestroyView();
mLeak = null; // now cleaning up!
}
除了保留参考文献之外View
你显然不应该保留对Activity
(例如来自onAttach
- 清洁上onDetach
)或任何Context
(除非它是Application
语境)。