【问题标题】:RecyclerView inside RecyclerView, app crashing due to high memory consumptionRecyclerView里面的RecyclerView,由于高内存消耗导致app崩溃
【发布时间】:2020-07-12 16:24:26
【问题描述】:

我想创建一个相册的回收视图,当用户点击相册时,它会展开为显示该相册中图像的网格布局。

例如,非扩展:

并展开:

外层recyclerView项目的布局只包含一个textView、checkbox和一个不可见的recyclerview,在点击item时可见。

我这样声明了 outerAdapter:

photosVideosAdapter = new PhotosVideosAdapter(getContext(),new ArrayList<PhoneAlbum>());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(photosVideosAdapter);

这里是外部适配器的onBindViewHolder:

holder.tvFolder.setText(phoneAlbums.get(position).getName());
ArrayList<PhonePhoto> phonePhotos = phoneAlbums.get(position).getAlbumPhotos();
InnerAdapter innerAdapter = new InnerAdapter(context, phonePhotos);
holder.innerRecyclerView.setHasFixedSize(true);
holder.innerRecyclerView.setLayoutManager(new GridLayoutManager(context,3));
holder.innerRecyclerView.setAdapter(innerAdapter);
.... OnClickMethod to toggle visibility of innerRecyclerView

内部适配器的 onBindViewHolder:

Glide.with(context)
        .load(phonePhotos.get(position).getPhotoUri())
        .override(200,200)
        .into(holder.imgThumbnail);

问题是如果内部 recyclerView 包含超过 200 个项目,应用程序会由于高内存使用而崩溃。但正如你所看到的,我正在使用 glide 加载图像,而且 RecyclerView 不应该一次创建所有视图。但是,我可以看到内部 RecyclerView 正在一次创建所有项目视图,这导致应用程序崩溃。

我该如何解决这个问题?任何帮助将不胜感激。

【问题讨论】:

  • 问题是内部 recyclerView 正在一次加载所有视图。所以,如果内部的 recyclerView 有 1000 张图片,所有的图片都是一次性加载的,这不是 recyclerView 应该做的。

标签: android android-recyclerview android-viewholder nestedrecyclerview


【解决方案1】:

相信我,不要在 recyclerview 中使用 recyclerview。 我在当前的应用程序中遇到了类似的情况,我的同事使用嵌套的 recyclerview 构建了解决方案。

我使用插入和删除动画和多视图类型重写了整个逻辑。 它将涉及一些额外的代码来管理它。但结果会很令人满意。

事实上,我在 iOS 的 collectionview 中也使用了相同的逻辑。两个平台上的应用都已上线。

【讨论】:

    【解决方案2】:

    尝试将其添加到您的 manifest.xml 中

            android:largeHeap="true"
    
    

    【讨论】:

    • 问题不在于增加堆大小。问题是内部回收器视图一次创建所有视图,因此,如果相册中有 4000 张照片,它将一次创建所有 4000 个视图。
    【解决方案3】:

    您的内存消耗可能很高,因为您使用以下行一次从相册中检索了所有照片:

    ArrayList<PhonePhoto> phonePhotos = phoneAlbums.get(position).getAlbumPhotos();
    

    我假设您还以原始质量提取所有照片,因此在手机 RAM 上同时拥有 200 多张全尺寸照片可能是导致崩溃的原因。

    解决此问题的一种方法是将照片的低分辨率预览加载到 RAM 中,一旦照片实际显示在 RecyclerView 中,您就可以加载全分辨率照片。

    【讨论】:

    • 测试这是否真的是问题的根本原因的一种方法是注释掉所有关于在 RecylcerView 中显示图片并查看内存使用率是否仍然很高的代码。
    • PhonePhoto 只包含图片的 URI,并且所有图片的 URI 都已经存储在 ArrayList 中。
    • 问题是内部回收器视图一次加载所有视图。因此,如果内部 recycler 视图有 1000 张图像,则所有图像都会一次加载,这不是 recyclerView 应该做的。
    • 你试过记录什么 layoutManager.getChildCount();返回,应该是当前加载的视图数
    • 对于innerRecyclerView,等于图片的个数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    相关资源
    最近更新 更多