gpt4 book ai didi

android - 为什么 viewHolders 没有被垃圾收集

转载 作者:行者123 更新时间:2023-11-30 00:26:40 24 4
gpt4 key购买 nike

我有一个 Activity ,我在其中替换充当每个屏幕的 fragment 。

我打开一个 fragment 并按下返回键(将它从 backstack 弹出)并返回到前一个 frag。然后,我按下“Initiate GC”按钮

enter image description here

然后我转储 Java 堆并获得以下内容。

enter image description here

似乎 fragment FMenuForm 没有从内存中释放,对吧?唯一似乎仍在内存中的是 RecyclerView 中使用的 ViewHolders ...但为什么呢?!

我在fragment的onDestroy()方法中设置了this.my_recycler_view.setAdapter(null),但是好像还是不想gc

enter image description here

编辑

这是 AdapterViewHolders 的代码。它们都是 FMenuForm

的内部类
public class FMenuForm extends Fragment{


private RecyclerView list_view;

private AdapterMenuForm mAdapter;

private int mIndexSelected = 0;

//
// PRIVATE IMPLEMENTATION
//

private ListItemClickCallback.OnListItemClickListener<AdapterMenuForm.ListItem> mItemClickCallback =
new ListItemClickCallback.OnListItemClickListener<AdapterMenuForm.ListItem>() {
@Override
public boolean onListItemClicked(View view, AdapterMenuForm.ListItem item, int position) {
//TODO:
}
};

/** Some other method and fields here */


//
// ADAPTERS
//

private class AdapterMenuForm extends RecyclerView.Adapter<RowHolder> {

private final int TYPE_SUBCATEGORY = 0;
private final int TYPE_THEME = 1;

private LayoutInflater mInflater;

private ArrayList<ListItem> mSubcategories;

//
// CONSTRUCTOR
//

public AdapterMenuForm() {
mInflater = LayoutInflater.from(getContext());
}

//
// ADAPTER
//


@Override
public int getItemCount() {
return mSubcategories == null ? 0 : mSubcategories.size();
}

@Override
public int getItemViewType(int position) {
return mSubcategories.get(position).isSubcategory() ? TYPE_SUBCATEGORY : TYPE_THEME;
}

@Override
public RowHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
if (type == TYPE_SUBCATEGORY) {
return new RowHolderSubcategory(mInflater.inflate(R.layout.list_item_form_menu_parent, viewGroup, false));
} else {
return new RowHolderTheme(mInflater.inflate(R.layout.list_item_form_menu_child, viewGroup, false));
}
}

@Override
public void onBindViewHolder(final RowHolder holder, int position) {

ListItem data = mSubcategories.get(position);

//Label
holder.text.setText(
data.isSubcategory()
? data.item.subcategory.name
: data.item.theme.name);

//Highlight
holder.itemView.setActivated(mIndexSelected == position);

//Check icon
//TODO:
holder.icon.setActivated(position % 2 == 0);

//Arrow
holder.arrow.setVisibility(
data.children.size() == 0 ? View.INVISIBLE : View.VISIBLE
);
holder.arrow.setImageResource(
data.isExpanded ? R.drawable.selector_expandable_icon_up : R.drawable.selector_expandable_icon_down
);

//Click listeners
holder.itemView.setOnClickListener(new ListItemClickCallback<ListItem>(mItemClickCallback, data, position));
holder.arrow.setOnClickListener(new ListItemClickCallback<ListItem>(mArrowClickCallback, data, position));


}

//
// PUBLIC IMPLEMENTATION
//

public void setData(final FormOptionsListItem items) {

/** Long method. Nothing interesting. Populated mSubcategories*/

}

//
// CLASSES
//

private class ListItem {

boolean isExpanded = false;

FormOptionItem item;

ArrayList<ListItem> children = new ArrayList<>();

public ListItem(FormOptionItem item) {
this.item = item;
}

public boolean isSubcategory() {
return item.remote_theme_id.contentEquals("0");
}

public boolean isTheme() {
return !item.remote_theme_id.contentEquals("0");
}

}

}

public static class RowHolder extends RecyclerView.ViewHolder {
private TextView text;
private View icon;
private ImageView arrow;

public RowHolder(View view) {
super(view);
this.text = (TextView) view.findViewById(R.id.list_item_form_menu_text);
this.icon = view.findViewById(R.id.list_item_form_check_icon);
this.arrow = (ImageView) view.findViewById(R.id.list_item_form_check_icon_arrow);
}
}

public static class RowHolderSubcategory extends RowHolder {
public RowHolderSubcategory(View view) {
super(view);
}
}

public static class RowHolderTheme extends RowHolder {
public RowHolderTheme(View view) {
super(view);
}
}

}

最佳答案

问题是您在类中定义了 AdapterMenuForm,但它不是静态的。按照EffectiveJava的文档,这是不合法的。(item22)

If you declare a member class that does not require access to an enclosing instance, always put the static modifier in its declaration , making it a static rather than a nonstatic member class. If you omit this modifier, each instance will have an extraneous reference to its enclosing instance. Storing this reference costs time and space, and can result in the enclosing instance being retained when it would otherwise be eligible for garbage collection ( Item 6 ). And should you ever need to allocate an instance without an enclosing instance, you'll be unable to do so, as nonstatic member class instances are required to have an enclosing instance.

解决方案是,尝试使您的 Adapter 类成为嵌套静态类或将其移动到另一个文件夹:adapters?然后创建一个 constructor 来初始化您的 mSubCategories

关于android - 为什么 viewHolders 没有被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45238152/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com