我不知道为什么这么推荐RecyclerView,我收到了很多内存泄漏。其中大多数是库泄漏,这是我无法控制的(如果我错了,请纠正我),但是现在我从ClickListener中遇到了内存泄漏。我看了看google,但我想不出点击监听器的最佳做法,因为它们的方法太多了。哦,为什么Android没有添加简单的解决方案?
我讨厌的最后一个Click Listener方法是来自下一个Youtube链接
RecyclerView OnClickListener (Best practice way) - is it really???
与我的实现和视频的不同之处在于,我将ViewHolder设为静态,但这仅是因为下一个链接中的android文档(顺便说一句,我只是因为我有一些库泄漏而改变了它,而且我认为这可能会解决它)
Android recyclerView documentation
代码如下:
public class CollaborateAdapter
extends FirestoreRecyclerAdapter < FireContact, CollaborateAdapter.CollaborateViewHolder > {
private Glist mGlist;
private ClickListener mOnClickListener;
CollaborateAdapter(@NonNull FirestoreRecyclerOptions < FireContact > options, Glist glist, ClickListener listener) {
super(options);
mOnClickListener = listener;
mGlist = glist;
}
public interface ClickListener {
void onClick(int i);
}
@NonNull
@Override
public CollaborateViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_collaborate, parent, false);
return new CollaborateViewHolder(view, mOnClickListener);
}
@Override
public void onBindViewHolder(@NonNull CollaborateViewHolder holder, int position,
@NonNull FireContact model) {
holder.mNameTextView.setText(model.getNa());
holder.mPhoneTextView.setText(model.getPho());
if (isCollaborator(model.getFuid())) {
holder.mAddImageView.setImageResource(R.drawable.baseline_remove_circle_24px);
} else {
holder.mAddImageView.setImageResource(R.drawable.baseline_add);
}
}
boolean isCollaborator(String contactUid) {
//.....
}
void updateGlist(Glist glist) {
mGlist = glist;
notifyDataSetChanged();
}
public static class CollaborateViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
TextView mNameTextView;
TextView mPhoneTextView;
ImageView mAddImageView;
ClickListener mListener;
CollaborateViewHolder(@NonNull View itemView, ClickListener clickListener) {
super(itemView);
mNameTextView = itemView.findViewById(R.id.list_collaborate_name_tv);
mPhoneTextView = itemView.findViewById(R.id.list_collaborate_phone);
mAddImageView = itemView.findViewById(R.id.list_collaborate_add_iv);
mListener = clickListener;
mAddImageView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.list_collaborate_add_iv) {
mListener.onClick(getAdapterPosition());
}
}
}
}
这是内存泄漏
┬───
│ GC Root: Local variable in native code
│
├─ android.net.ConnectivityThread instance
│ Leaking: NO (PathClassLoader↓ is not leaking)
│ Thread name: 'ConnectivityThread'
│ ↓ ConnectivityThread.contextClassLoader
├─ dalvik.system.PathClassLoader instance
│ Leaking: NO (CollaborateAdapter↓ is not leaking and A ClassLoader is never leaking)
│ ↓ PathClassLoader.runtimeInternalObjects
├─ java.lang.Object[] array
│ Leaking: NO (CollaborateAdapter↓ is not leaking)
│ ↓ Object[].[1559]
├─ com.android.rangroceryshopping.collaborate.CollaborateAdapter class
│ Leaking: NO (a class is never leaking)
│ ↓ static CollaborateAdapter.mOnClickListener
│ ~~~~~~
╰→ com.android.rangroceryshopping.collaborate.CollaborateActivity instance
Leaking: YES (ObjectWatcher was watching this because com.android.rangroceryshopping.collaborate.CollaborateActivity received Activity#onDestroy() callback and Activity#mDestroyed is true)
key = 2ac23d62-e7b9-49c8-b881-b8f32592027a
watchDurationMillis = 5353
retainedDurationMillis = 351
METADATA
Build.VERSION.SDK_INT: 28
Build.MANUFACTURER: samsung
LeakCanary version: 2.2
App process name: com.android.rangroceryshopping
Analysis duration: 19112 ms