在我的应用程序中,我有一个包含3个片段的ViewPage的MainActivity。其中两个片段有一些由一些CardView填充的RecyclerView。一切正常,但在安装金丝雀泄漏后,我注意到我的RecyclerViews正在泄漏MainActivity:
看起来应该有静态引用阻止GC完成他的工作,但我的代码中没有这样的东西。我试过打电话
recyclerView.setAdapter(null) or recyclerView.cleanup()
在我的Fragment的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);
}
这是我的ViewHolder:
public class MyEventViewHolder extends RecyclerView.ViewHolder{
View mView;
CircularImageView cardProfile;
TextView cardLikes,cardDate,cardTime;
TextView event_name,joiners,etaMedia,maleSex,cardPrice,femaleSex;
FABRevealLayout mFABRevealLayout;
Button chiudi;
FloatingActionButton fabLike;
public MyEventViewHolder(View itemView) {
super(itemView);
mView=itemView;
//removed some UI declaration and methods for readability
cardTime = (TextView)mView.findViewById(R.id.cardTime);
fabLike = (FloatingActionButton)mView.findViewById(R.id.fabLike);
}
public void setThumbUp (){
fabLike.setImageResource(R.drawable.white_star_empty_24);
}
public void setThumbDown (){
fabLike.setImageResource(R.drawable.white_star_full_24);
}
我不知道这是否有用,但泄漏通常是14KB到最大50KB。我已经能够解决所有其他泄漏问题,但这个问题让我疯狂了
答案 0 :(得分:0)
您的recyclerView是静态的吗?
无论如何,你应该在onDestroyView中将recyclerView设置为null(recyclerView = null
)(因为它在onCreateView中初始化)。
答案 1 :(得分:0)
我认为问题出现以下问题:
mDatabaseLike.addValueEventListener(likeCheckerListener);
你可以简单地评论它,看看是否还在发生泄漏。
您的likeCheckerListener是Anonymous类的Object,它引用了通过重写FirebaseRecyclerAdapter创建的Anonymous类,该类具有对您的活动的引用。这导致泄漏。
为了能够安全地处理这种情况,您应该为每个添加到mDatabase的ValueEventListener维护一个引用,并在onStop / onDestroy方法中将它们全部删除。
为此,你可能应该与听众和他们正在聆听的关键词保持一张地图。
还要考虑覆盖FirebaseRecyclerAdapter的onViewRecycled()方法,然后您还可以在回收视图时逐个删除侦听器,并且只侦听实际需要的项目上的事件。