首页 > 解决方案 > RecyclerView 需要很长时间才能从用户存储中填充大量视频

问题描述

所以我使用 Glide 加载视频缩略图,但是加载大量视频需要一段时间才能查看,在 Recycler 视图中,使用每个视频缩略图在用户手机中加载视频列表的最佳/最快方法是什么.

填充列表

    public static ArrayList<String> getAllMedia(Context context) {
    HashSet<String> videoItemHashSet = new HashSet<>();
    String[] projection = { MediaStore.Video.VideoColumns.DATA ,MediaStore.Video.Media.DISPLAY_NAME};
    Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
    try {
        cursor.moveToFirst();
        do{
            videoItemHashSet.add((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))));
        }while(cursor.moveToNext());

        cursor.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    ArrayList<String> downloadedList = new ArrayList<>(videoItemHashSet);
    return downloadedList;
}

滑行法

    public static void displayImageOriginal(Context ctx, ImageView img, String url) {
    try {
        Glide.with(ctx).load(url)
                .transition(DrawableTransitionOptions.withCrossFade())
                .apply(RequestOptions.centerCropTransform().skipMemoryCache(false).diskCacheStrategy(DiskCacheStrategy.ALL))
                .into(img);
    } catch (Exception e) {
    }
}

这是适配器视图活页夹

    @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    final YVideos obj = items.get(position);
    if (holder instanceof OriginalViewHolder) {
        OriginalViewHolder view = (OriginalViewHolder) holder;

        view.video_title.setText(obj.title);
        view.duration_size.setText(obj.getDurSize());
        Tools.displayImageOriginal(ctx, view.video_thumbnail, obj.name);
    } else {
        SectionViewHolder view = (SectionViewHolder) holder;
        view.title_section.setText(obj.title);
    }
}

标签: javaandroidandroid-recyclerviewandroid-glide

解决方案


这一切看起来都像标准RecyclerView用法,所以如果您的适配器被单独分配给RecyclerView,即没有定义任何限制性能的属性,例如setItemViewCacheSize()setMaxRecycledViews()等等,您的问题不太可能是客户端问题。

您是否依赖于Glide在运行时为您生成缩略图?如果是这样,您将真正通过大量处理使库通过其步伐,因为它必须在运行中处理原始质量、原始分辨率的视频。难道不能事先生成缩略图吗?这些将更快地加载并减轻您的应用程序的大量计算负担。如果缩略图将永远保持不变,那么为什么不计算一次并让每个用户受益,而不是让每个用户在每次渲染时都计算相同的结果呢?

在我看来,您的问题很可能来自这样一个事实,即您希望获取图像并将它们呈现给用户,而他们已经在查看内容。这意味着您加载屏幕并被onBindViewHolder()调用,并且您尝试从网络获取图像;但在这个阶段,用户已经在查看列表并准备浏览。在某种程度上,你有点太晚了,你List的速度只会和你的网络连接/图像服务器一样快。

您可以做的是在尝试绘制RecyclerView. 您在到达该屏幕之前就知道要渲染的图像范围;甚至在你准备好画画之前,就有可能将load这些纳入Glide并定义一个合适的。diskStrategy这样,您可以List在用户正在查看的那一刻初始化内容。预测图像缓存策略不会到此结束;您知道接下来准备加载哪些图像行;所以你也可以在后台获取那些。这种方法的缺点是它可能会浪费大量带宽来获取用户可能永远不会向下滚动的图像;因此,您可能需要尝试请求速率限制。

还有一些更狡猾的方法可以解决这个问题。即使是资金最充足、研究最充分的应用程序也依赖于解决网络性能瓶颈的简单技巧……您是否考虑过使用占位符动画来保持您的应用程序看起来活跃?你会惊讶于这些工作的效果!


推荐阅读