Лучшая практика RecyclerView click listener без утечек памяти - PullRequest
0 голосов
/ 06 марта 2020

Я не могу понять, почему RecyclerView так рекомендуется, у меня так много утечек памяти. Большинство из них - Утечки Библиотеки, которые находятся вне моего контроля (пожалуйста, исправьте меня, если я ошибаюсь), но теперь я получил утечку памяти от ClickListener. Я посмотрел на Google, и я не могу понять лучшую практику для Слушателей щелчка, так как их очень много подходов. о, почему android не добавил простое решение ??

Последний подход прослушивания щелчков, который я устал, был от следующей ссылки Youtube

RecyclerView OnClickListener (наилучшая практика) - действительно ли это ???

Разница с моей реализацией и видео заключалась в том, что я сделал ViewHolder stati c, но это было только после документации android в следующей ссылке (которая Кстати, я только изменился, потому что у меня были некоторые утечки в библиотеке, и я думал, что это может исправить это)

Android recyclerView документация

Вот код:

    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
...