Утечки памяти в RecyclerView android - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть RecyclerView во фрагменте. Я уверен, что утечка памяти произошла из RecyclerView, потому что, когда я добавляю RecyclerView, появляется утечка памяти.

Это мой адаптер RecyclerView:

public class TabsAdapter extends RecyclerView.Adapter<TabsAdapter.SetViewHolder> {

private Context context;
private List<TabsModel> items = Collections.emptyList();
private TabsDatabaseHelper databaseHelper;
private Dialog dialog;

public TabsAdapter(Context context, List<TabsModel> items, Dialog dialog) {
    databaseHelper = new TabsDatabaseHelper(context);
    this.context = context;
    this.items = items;
    this.dialog = dialog;
}

@NonNull
@Override
public TabsAdapter.SetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_tabs, parent, false);
    return new SetViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull TabsAdapter.SetViewHolder holder, final int position) {
    //I clean here codes, By removing the code here, Memory Leak again occur
}

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

static class SetViewHolder extends RecyclerView.ViewHolder {

    private ImageView ivShot, ivRemove;
    private TextView tvTitle, tvUrl;
    private ConstraintLayout constraintLayout;

    private SetViewHolder(@NonNull View itemView) {
        super(itemView);
        ivShot = itemView.findViewById(R.id.iv_item_tabs);
        ivRemove = itemView.findViewById(R.id.iv_clear_item_tabs);
        tvTitle = itemView.findViewById(R.id.tv_title_item_tabs);
        tvUrl = itemView.findViewById(R.id.tv_url_item_tabs);
        constraintLayout = itemView.findViewById(R.id.const_item_tabs);
    }
}
}

И во фрагменте:

    tabsModelArrayList.clear();
    tabsModelArrayList = tabsDatabaseHelper.getData();
    tabsAdapter = new TabsAdapter(context, tabsModelArrayList, getDialog());
    recyClerView.setHasFixedSize(true);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
    recyClerView.setLayoutManager(linearLayoutManager);
    recyClerView.setAdapter(tabsAdapter);

Итак, утечка памяти:

leakcanary library

Я пытаюсь установить нулевое представление в адаптере:

@Override
public void onViewDetachedFromWindow(@NonNull SetViewHolder holder) {
    super.onViewDetachedFromWindow(holder);
    holder.constraintLayout = null;
    holder.ivRemove = null;
    holder.ivShot = null;
    holder.tvTitle = null;
    holder.tvUrl = null;
}

Или в Во фрагменте Десроя я установил:

recyClerView.setAdapter(null);

Но у меня все еще есть эта ошибка. Вы можете мне помочь?

---------- Редактировать

Я удаляю Context и DatabaseHelper из Adapter:

public class TabsAdapter extends RecyclerView.Adapter<TabsAdapter.SetViewHolder> {

private List<TabsModel> items = Collections.emptyList();
private Dialog dialog;

public TabsAdapter(List<TabsModel> items, Dialog dialog) {
    this.items = items;
    this.dialog = dialog;
}

@NonNull
@Override
public TabsAdapter.SetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_tabs, parent, false);
    return new SetViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull TabsAdapter.SetViewHolder holder, final int position) {
    //I clean here codes, By removing the code here, Memory Leak again occur
}

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

static class SetViewHolder extends RecyclerView.ViewHolder {

    private ImageView ivShot, ivRemove;
    private TextView tvTitle, tvUrl;
    private ConstraintLayout constraintLayout;

    private SetViewHolder(@NonNull View itemView) {
        super(itemView);
        ivShot = itemView.findViewById(R.id.iv_item_tabs);
        ivRemove = itemView.findViewById(R.id.iv_clear_item_tabs);
        tvTitle = itemView.findViewById(R.id.tv_title_item_tabs);
        tvUrl = itemView.findViewById(R.id.tv_url_item_tabs);
        constraintLayout = itemView.findViewById(R.id.const_item_tabs);
    }
}

@Override
public void onViewDetachedFromWindow(@NonNull SetViewHolder holder) {
    super.onViewDetachedFromWindow(holder);
    holder.constraintLayout = null;
    holder.ivRemove = null;
    holder.ivShot = null;
    holder.tvTitle = null;
    holder.tvUrl = null;
}
}

Но не исправляю память протечь.

1 Ответ

0 голосов
/ 01 апреля 2020

Я могу предложить вам две вещи. Во-первых, вы не должны отправлять Context в своем конструкторе адаптера recyclerView. В вашем коде вы в любом случае использовали его в OnCreateView как parent.getContext. Отправка контекста в вашем конструкторе вызывает утечки памяти. Во-вторых, я думаю, что вы не должны инициализировать DatabaseHelper в своем конструкторе. Это можно сделать до создания экземпляра адаптера. Получите список из базы данных и отправьте его вместо DatabaseHelper в конструкторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...