java - RecyclerView 花费太长时间从用户存储中填充大量视频

标签 java android android-recyclerview android-glide

所以我正在使用 Glide 来加载视频缩略图,但是加载大量视频以供查看需要一段时间,在用户手机中加载每个视频缩略图的视频列表的最佳/最快方法是什么,在回收站 View 中。

填充列表

    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;
}

Glide 法

    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) {
    }
}

这里是适配器 View Binder

    @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);
    }
}

最佳答案

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

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

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

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

还有一些更巧妙的方法可以解决这个问题。即使是资金最充裕、研究最充分的应用程序也依赖于简单的技巧来解决网络性能瓶颈……您是否考虑过使用 placeholder animation让您的应用程序看起来活跃?您会惊讶于它们的效果!

关于java - RecyclerView 花费太长时间从用户存储中填充大量视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51839556/

相关文章:

java - 在运行时运行 Gluon-Mobile 应用程序时请求 Wifi 权限

java - 使用 ASM 访问 Java Stack 中的第二个顶级对象

android模拟器错误:[2011-08-02 11:14:01 - Emulator] PANIC: Could not open: C:\Users\hallo\. android/avd/myemu.ini

android - 如何在 android 中滚动时放大 Recycler View 中心项目?

java - SpringMVC ajax 请求 - java.io.EOFException : No content to map to Object due to end of input

java - 用一个 <br> 替换所有连续的 "\r\n or\n"

android - android中的SUM sqlite列 double 值

android - 如何在SQLite数据库浏览器中查看数据?

android - RecyclerView 项目背景交替颜色乱序

android - 如何在 MVP 模式中处理适配器