Android 片段中的RecyclerView泄漏父活动
在我的应用程序中,我有一个包含3个片段的查看页面的主活动。其中两个片段有一个由一些CardView填充的RecyclerView。一切正常,但在安装canary leaks后,我注意到我的RecyclerViews正在泄漏主要活动: 看起来应该有静态引用来阻止GC完成他的工作,但在我的代码中没有这样的东西。我试过打电话Android 片段中的RecyclerView泄漏父活动,android,android-fragments,memory-leaks,android-recyclerview,android-adapter,Android,Android Fragments,Memory Leaks,Android Recyclerview,Android Adapter,在我的应用程序中,我有一个包含3个片段的查看页面的主活动。其中两个片段有一个由一些CardView填充的RecyclerView。一切正常,但在安装canary leaks后,我注意到我的RecyclerViews正在泄漏主要活动: 看起来应该有静态引用来阻止GC完成他的工作,但在我的代码中没有这样的东西。我试过打电话 recyclerView.setAdapter(null) or recyclerView.cleanup() 在我的片段的onDestroy/onDestroyView上,但
recyclerView.setAdapter(null) or recyclerView.cleanup()
在我的片段的onDestroy/onDestroyView上,但泄漏仍然存在
这是我的片段:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//here some FirebaseDatabasereference
recyclerView = (RecyclerView)inflater.inflate(R.layout.event_fragment_layout, container,false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return recyclerView;
}
public void onStart() {
super.onStart();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Event, MyEventViewHolder>(
Event.class,
R.layout.event_card,
MyEventViewHolder.class,
myDatabase.child("Events").orderByChild(ordering[orderingSelector]),
) {
@Override
protected void populateViewHolder(final MyEventViewHolder viewHolder, final Event model, final int position) {
final String post_key = getRef(position).getKey();
viewHolder.setEventName(model.getEventName());
viewHolder.setEventImage(getApplicationContext(),model.getEventImagePath());
ValueEventListener likeCheckerListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.child(post_key).hasChild(currentUser.getUid())){
viewHolder.setThumbDown();
mDatabaseLike.removeEventListener(this);
}else{
viewHolder.setThumbUp();
mDatabaseLike.removeEventListener(this);
}
mDatabaseLike.removeEventListener(this);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
mDatabaseLike.addValueEventListener(likeCheckerListener);
recyclerView.setAdapter(firebaseRecyclerAdapter);
}
@Override
public void onStop() {
super.onStop();
recyclerView.setAdapter(null);
}
@Override
public void onDestroy() {
super.onDestroy();
recyclerView.setAdapter(null);
}
@Override
public void onDestroyView() {
super.onDestroyView();
recyclerView.setAdapter(null);
}
我不知道这是否有用,但泄漏通常是从14KB到最大50KB。我已经能够解决所有其他泄漏,但这一次让我发疯了你的recyclerView是静态的吗?
无论如何,您应该在onDestroyView中将recyclerView设置为null(
recyclerView=null
)(它在onCreateView中初始化)。您的recyclerView是静态的吗?
无论如何,您应该在onDestroyView中将recyclerView设置为null(
recyclerView=null
)(因为它在onCreateView中初始化)。我认为问题在于以下调用:
mDatabaseLike.addValueEventListener(likeCheckerListener);
您可以简单地对其进行评论,看看泄漏是否仍在发生
您的likeCheckerListener是匿名类的对象,该类引用了通过重写FirebaseRecyclerAdapter创建的匿名类,FirebaseRecyclerAdapter引用了您的活动。这导致了泄漏
为了能够安全地处理此场景,您应该为添加到mDatabase的每个ValueEventListener维护一个引用,并在onStop/onDestroy方法中删除它们
为此,您可能应该为您的侦听器和他们正在侦听的键维护一个映射
还考虑重写FiBaseReCyrEnter适配器的OnVIEWReCyReCd()方法,然后也可以在视图被回收时逐个删除侦听器,并且只侦听实际需要的项上的事件。
< P>我认为问题是以下调用:mDatabaseLike.addValueEventListener(likeCheckerListener);
您可以简单地对其进行评论,看看泄漏是否仍在发生
您的likeCheckerListener是匿名类的对象,该类引用了通过重写FirebaseRecyclerAdapter创建的匿名类,FirebaseRecyclerAdapter引用了您的活动。这导致了泄漏
为了能够安全地处理此场景,您应该为添加到mDatabase的每个ValueEventListener维护一个引用,并在onStop/onDestroy方法中删除它们
为此,您可能应该为您的侦听器和他们正在侦听的键维护一个映射
还考虑重写FiBaseReCyrEnter适配器的OnVIEWReCyReCd()方法,然后也可以在视图被回收时逐个删除侦听器,只在实际需要的项上侦听事件。
我的DealReVIEW不是静态的,我已经尝试调用OnDeStYy中的RealReVIEW。SETAdvad(NULL),onDestroView和onStop()如果未成功,则应设置recyclerView=null和adapter firebaseRecyclerAdapter=null。我的recyclerView不是静态的,我已尝试分别在onDestoy、onDestroView和onStop()中调用recyclerView.setAdapter(null)如果未成功,则应将recyclerView=null和adapter firebaseRecyclerAdapter=null。您还可以在onDestroy中调用recyclerAdapter.cleanup()
。此问题类似于:,但在您的情况下,recyclerAdapter.setAdapter(null)
没有帮助。感谢您在@OnDestroyViewy中调用recyclerAdapter.cleanup()显然起到了作用。您也可以在onDestroy中调用recyclerAdapter.cleanup()
。此问题类似于:,但在您的案例中,recyclerView.setAdapter(null)
没有帮助。感谢您,调用@onDestroyViewmy likeCheckerListener中的recyclerAdapter.cleanup()显然起到了作用,因为在dataSnapshot块中使用ref.RemovelListener(This)将其删除,正如我在上面所评论的,解决方案是调用setAdapter(null)是的,你是对的。我不知道为什么我没有看到;)我的likeCheckerListener在dataSnapshot块中与ref.RemovelListener(this)一起被删除,正如我在上面所评论的,解决方案是调用setAdapter(null)和cleanup()。是的,您是对的。我不知道为什么我没有看到;)