x-t*_*eme 16 android listview android-recyclerview
我曾经ListView在我的Android应用程序中使用,我最近切换到RecyclerView并观察到它在方向更改时引入了一些内存泄漏.经过进一步调查,原因显而易见
建立
activity托管a 的单个fragment,其实例在配置更改时保留.在fragment包含了一个RecyclerView在其布局文件中使用自定义填充adapter
钻井
只要Adapter为这两个视图中的任何一个设置了一个视图,它们就会使用适配器注册自己,以监视数据的更改并在UI上进行更新.ListView取消注册配置更改
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
...
if (mAdapter != null && mDataSetObserver != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
mDataSetObserver = null;
}
...
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,RecyclerView不这样做
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mItemAnimator != null) {
mItemAnimator.endAnimations();
}
mFirstLayoutComplete = false;
stopScroll();
mIsAttached = false;
if (mLayout != null) {
mLayout.onDetachedFromWindow(this, mRecycler);
}
removeCallbacks(mItemAnimatorRunner);
}
Run Code Online (Sandbox Code Playgroud)
证明
我改变了方向很多次然后进行堆转储,并使用Eclipse的MAT读取它.我确实看到我的活动有很多实例,因为RecyclerView实例没有unregister,他们对我的活动有很强的参考!
我错过了什么吗?你们如何确保RecyclerView不泄漏你的活动?
分段
public class ExampleFragment extends Fragment {
private ExampleAdapter mAdapter = null;
public static ExampleFragment newInstance() {
return new ExampleFragment();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
setupAdapterIfRequired();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_example, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setupRecyclerView(getView());
}
private void setupAdapterIfRequired() {
if (mAdapter == null) {
mAdapter = new ExampleAdapter();
}
}
private void setupRecyclerView(View rootView) {
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(mAdapter);
}
}
Run Code Online (Sandbox Code Playgroud)
InT*_*nds 23
将此添加到Fragment我的已停止泄漏:
@Override
public void onDestroyView() {
super.onDestroyView();
recyclerView.setAdapter(null);
}
Run Code Online (Sandbox Code Playgroud)
这不是 RecyclerView 的问题。这是因为你正在设置setRetainInstance(true)。
setRetainInstance()只能与没有视图的片段一起使用,否则会导致内存泄漏。
当方向更改活动将被终止时,但片段中的视图仍使用该活动的上下文。这就是您看到内存泄漏的原因。
| 归档时间: |
|
| 查看次数: |
7049 次 |
| 最近记录: |