内存不足错误在Glide中加载更多图像时

Luf*_*ffy 14 java android out-of-memory

编辑:

  • 在我的应用程序中,我在主页上加载了300多个图像.我glide以前加载图像.我到了Out of Memory Error.

我在清单中使用了大堆true :

android:largeHeap="true"
Run Code Online (Sandbox Code Playgroud)

滑翔版:

compile 'com.github.bumptech.glide:glide:3.7.0'
Run Code Online (Sandbox Code Playgroud)

设备/ Android版本:

Nexus Device 6.0版本

我从Json得到的每张图片都是800kb到1mb.

activity_layout:

<RelativeLayout
    android:id="@+id/home_layout_bottom"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/home_layout_top_recycler"
    android:layout_margin="5dp">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_list_tab_home_recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:scrollbars="vertical"
        android:visibility="visible" />

    <TextView
        android:id="@+id/no_user_posts_item_tv_recycler"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/rv_list_tab_home_recycler"
        android:layout_marginTop="80dp"
        android:layout_centerHorizontal="true"
        android:text="@string/txt_no_posts_available"
        android:textColor="@color/txt_common_black"
        android:textSize="@dimen/txt_size" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

适配器代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;

    final HomePostItems rowItem = getItem(position);

    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {

        convertView = mInflater.inflate(R.layout.lv_adapter_post_items_layout, null);

      holder = new ViewHolder();

      holder.ivPostedImage = (ImageView) convertView.findViewById(R.id.iv_posted_img);


        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

      ..................

          Glide.with(context).load(rowItem.getPosteduserpostimage())
                        .placeholder(R.drawable.golive_load_image).error(R.drawable.golive_cancel_image)
                        .override(600, 200)
                        .into(holder.ivPostedImage);
Run Code Online (Sandbox Code Playgroud)

adapter_layout.xml:

<RelativeLayout
    android:id="@+id/rl_lv_user_post_adapter_img_holder_home"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:layout_marginLeft="1dp"
    android:layout_marginRight="1dp"
    android:layout_below="@+id/tv_user_posted_msg_post_items_home" >

    <ImageView
        android:id="@+id/iv_posted_img_home"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:scaleType="fitXY"
        android:background="#ffffff"
        android:contentDescription="@string/cont_desc"/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

logcat的:

Request threw uncaught throwable
java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Failed to allocate a 6365196 byte allocation with 865912 free bytes and 845KB until OOM
at java.util.concurrent.FutureTask.report(FutureTask.java:94)
at java.util.concurrent.FutureTask.get(FutureTask.java:164)
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor.afterExecute(FifoPriorityThreadPoolExecutor.java:96)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1121)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 6365196 byte allocation with 865912 free bytes and 845KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decodeStream(Downsampler.java:329)
at com.bumptech.glide.load.resource.bitmap.Downsampler.downsampleWithSize(Downsampler.java:220)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:153)
at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:50)
at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:19)
at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:39)
at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:20)
at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeBitmapWrapper(GifBitmapWrapperResourceDecoder.java:121)
at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeStream(GifBitmapWrapperResourceDecoder.java:94)
at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:71)
at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:61)
at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:22)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromSourceData(DecodeJob.java:190)
at com.bumptech.glide.load.engine.DecodeJob.decodeSource(DecodeJob.java:177)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromSource(DecodeJob.java:128)
at com.bumptech.glide.load.engine.EngineRunnable.decodeFromSource(EngineRunnable.java:122)
at com.bumptech.glide.load.engine.EngineRunnable.decode(EngineRunnable.java:101)
at com.bumptech.glide.load.engine.EngineRunnable.run(EngineRunnable.java:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
Run Code Online (Sandbox Code Playgroud)

我不知道如何解决这个OOM问题.如果您已经熟悉此问题,请分享您的建议.

Luf*_*ffy 12

  • 我通过删除置于recyclerview上方的嵌套滚动视图解决了这个问题.为什么发生OutOfMemory错误意味着,当在主页中加载超过200个图像时,由于在recyclerview上方使用嵌套滚动视图,因此它正在加载所有200个图像.

  • 所以我无法在适配器中逐个检查logcat图像视图的宽度和高度.

  • 删除嵌套滚动视图后修复了内存错误.因为它只会在进入家庭活动时加载设备中显示的3个图像.

  • 另外检查 一下,如何使用滚动而不是嵌套滚动视图.


Rea*_*hed 9

这不是您问题的精确解决方案,但是您需要在使用Glide在列表中加载图像时记住这些事项.

您问题的主要威胁部分是图像大小.你得到的图像几乎是1mb!实际上,将它们显示为具有300多个项目的列表实际上太大了.因此,如果您也在服务器端,它总是建议使用几种不同大小的图像.

例如,如果显示朋友列表及其个人资料图片,我建议您先从服务器获取整个列表.然后获取所有配置文件图像并将其存储在本地.然后填充ListView.最重要的部分是在将用户的个人资料图片上传到服务器时,在上传之后,服务器需要保留几种尺寸,例如低,中和高分辨率版本.因此,在提供ListView服务器的配置文件时,服务器的URL 可能会提供低分辨率的图像,因为它们最有可能用于缩略图.

使用RecyclerView而不是ListView一个好的电话.但是当你处于低端设备时,它无法解决你在这里遇到的问题.

OMM与你无关,你可以以编程方式解决.您需要将图像调整为较低版本.

您也可以检查Glide的缓存机制.我建议你使用缓存策略,这样每次你不必从服务器加载图像.

祝好运.


Mur*_*ain 7

使用 Glide 并不能保证没有Out of Memory错误,你需要使用几个小步骤来减少没有得到OOM's.

第一步:理解Glide 中的缓存机制

第 2 步:我更喜欢加载thumbnails到 recyclerview

Glide  
    .with( context )
    .load( UsageExampleGifAndVideos.gifUrl )
    .thumbnail( 0.1f )
    .into( imageView2 );
Run Code Online (Sandbox Code Playgroud)

如果不需要更大或高清图像,请记住始终请求小尺寸图像。


sub*_*ati 5

使用recyclerView代替ListView。它可重复使用单个项目来渲染项目。我使用gliderecyclerView我在哪里加载与壁纸100+项目。

在每次创建视图时在 ListView 中,如果您有 100 多个视图,它将创建 100 多个视图,而在 recyclerview 中,它会创建屏幕 +2 中有多少可见项目。

  • ListView 不会创建 100 多个视图,而是重用旧视图 - `convertView`。所以这不是个案。@Naruto 您的测试设备上的 Android 版本是什么? (5认同)

Jam*_*mim 5

  1. 确保ImageView具有match_parent或固定的dp,因为wrap_content的尺寸使Glide加载全分辨率位图。
  2. .placeholder()在加载大位图时显示图像而不是空白
  3. .thumbnail(float)快速加载降采样的版本,而背景中加载较大的图像
  4. 同时查看Glide问题,也许您会发现有用的信息。