使用 Glide 冻结 RecyclerView

RecyclerView freezing with Glide

我在游标适配器中使用滑行来加载数千个视图。它们都附有从磁盘加载的小图像(均小于 10kb)。但是我越来越僵硬,问题似乎来自 Glide 库(但它可能是由于 cursorloader)。我在下面附上了我的代码和日志文件。

相关 CursorAdapter 代码:

public FilesFragmentCursorAdapter(Activity context, Cursor cursor, Bucket bucket) {
        super(context, cursor, 0);
        mContext = context;
        this.cursor = cursor;
        mBucket = bucket;
        mSelectedItemsIds = new SparseBooleanArray();
        downloader = new ThumbnailDownloader(mContext, mBucket);
        manager = GlideApp.with(mContext);
        inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mShowThumbnails = mContext.getSharedPreferences(Constants.PREFS, Context.MODE_PRIVATE).getBoolean(Constants.PREFS_SHOW_THUMBNAILS, false);
    }

    @Override
    public Object getItem(int position) {
        return super.getItem(position);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
        return LayoutInflater.from(context).inflate(R.layout.list_file_item, viewGroup, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        FileViewHolder holder = new FileViewHolder();

        holder.mId = view.findViewById(R.id.list_file_id);
        holder.mName = view.findViewById(R.id.list_file_name);
        holder.mSize = view.findViewById(R.id.list_file_size);
        holder.mCreated = view.findViewById(R.id.list_file_date);
        holder.image = view.findViewById(R.id.list_file_image);
        holder.container = view.findViewById(R.id.list_file_item);

        String id = cursor.getString(cursor.getColumnIndex(KEY_PID));
        String name = cursor.getString(cursor.getColumnIndex(KEY_NAME));
        long size = cursor.getLong(cursor.getColumnIndex(KEY_SIZE));
        String created = cursor.getString(cursor.getColumnIndex(KEY_CREATED_AT));
        String mimeType = cursor.getString(cursor.getColumnIndex(KEY_MIME));

        if (id != null) holder.mId.setText(id);
        if (name != null) holder.mName.setText(name);
        String fileSize = Formatter.formatFileSize(mContext, size);
        holder.mSize.setText(fileSize);
        if (created != null && created.length() > 10) {
            String fileCreatedDate = created.substring(0, 10);
            holder.mCreated.setText(fileCreatedDate);
        }
        if (mimeType != null) {
            if (mimeType.contains("image")) {
                holder.image.setImageResource(R.drawable.ic_image_black_48dp);
                if (mShowThumbnails) {
                    String thumbnailPath = cursor.getString(cursor.getColumnIndex(KEY_THUMBNAIL));
                    if (!TextUtils.isEmpty(thumbnailPath)) {
                        manager.load(thumbnailPath).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE).into(holder.image);
                    } else {
                        File current = DatabaseHelper.createFileFromCursor(cursor);
                        downloader.download(current);
                    }
                }
            } else if (mimeType.contains("video")) {
                holder.image.setImageResource(R.drawable.ic_videocam_black_48dp);
            } else if (mimeType.contains("text")) {
                holder.image.setImageResource(R.drawable.ic_text_format_black_48dp);
            } else if (mimeType.contains("audio")) {
                holder.image.setImageResource(R.drawable.ic_audiotrack_black_48dp);
            } else {
                holder.image.setImageResource(R.drawable.ic_insert_drive_file_black_48dp);
            }
        }
    }

日志:

12-28 21:47:17.212 27355-27450/co.intellidev.storj E/Parcel: fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 0, fds[i] is -1, fd_count is 1, error: Too many open files
12-28 21:47:20.150 27355-27752/co.intellidev.storj E/libEGL: error creating cache file /data/user_de/0/co.intellidev.storj/code_cache/com.android.opengl.shaders_cache: Too many open files (24)
12-28 21:50:02.744 27355-27450/co.intellidev.storj E/GraphicBuffer: unflatten: registerBuffer failed: Unknown error -5 (5)
12-28 21:50:02.748 27355-27450/co.intellidev.storj E/Surface: dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: 5
12-28 21:50:02.752 27355-27450/co.intellidev.storj E/Parcel: fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 1, fds[i] is -1, fd_count is 2, error: Too many open files
12-28 21:50:02.752 27355-27450/co.intellidev.storj E/Surface: dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: -22
12-28 21:50:02.754 27355-27450/co.intellidev.storj E/Parcel: fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 1, fds[i] is -1, fd_count is 2, error: Too many open files
12-28 21:50:02.754 27355-27450/co.intellidev.storj E/Surface: dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: -22

如讨论..

public class FilesFragmentCursorAdapter extends RecyclerView.Adapter<FilesFragmentCursorAdapter.FileViewHolder > {
/* objects */
public FilesFragmentCursorAdapter(Activity context, Cursor cursor, Bucket bucket) {
    mContext = context;
    this.cursor = cursor;
    mBucket = bucket;
    mSelectedItemsIds = new SparseBooleanArray();
    downloader = new ThumbnailDownloader(mContext, mBucket);
    manager = GlideApp.with(mContext);
    inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mShowThumbnails = mContext.getSharedPreferences(Constants.PREFS, Context.MODE_PRIVATE).getBoolean(Constants.PREFS_SHOW_THUMBNAILS, false);
}


@Override
public FilesFragmentCursorAdapter.FileViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_file_item, parent, false);
    return new FileViewHolder(itemView); // <- render view here
}

@Override
public void onBindViewHolder(FilesFragmentCursorAdapter.FileViewHolder  holder, final int position) {
    String id = cursor.getString(cursor.getColumnIndex(KEY_PID));
    String name = cursor.getString(cursor.getColumnIndex(KEY_NAME));
    long size = cursor.getLong(cursor.getColumnIndex(KEY_SIZE));
    String created = cursor.getString(cursor.getColumnIndex(KEY_CREATED_AT));
    String mimeType = cursor.getString(cursor.getColumnIndex(KEY_MIME));


    if (id != null) holder.mId.setText(id);
    if (name != null) holder.mName.setText(name);

}



@Override
public int getItemCount() {
    return contactsList.size();
}

public class FileViewHolder  extends RecyclerView.ViewHolder {
    private TextView mId;
    private TextView mName;
    private TextView mSize;
    // so on
    public FileViewHolder (View view) {
        super(view);
        mId = view.findViewById(R.id.list_file_id);
        mName = view.findViewById(R.id.list_file_name);
        mSize = view.findViewById(R.id.list_file_size);
        // so on


    }
}
}

相应地更新您的适配器 class。


我想知道你为什么跳过缓存而不是存储在缓存中。

manager.load(thumbnailPath).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE).into(holder.image);

对此进行更改并允许 glide 缓存生成的图像而不是原始图像。

manager.load(thumbnailPath).diskCacheStrategy(DiskCacheStrategy.RESULT).into(holder.image);