I am writing a simple demo to show a list of images from network using the Glide,but I got an OutOfMemoryError.
When I fling the ListView,the app became lagged and threw OutOfMemoryErrors but had no crash.
The code in ListView adapter:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_view, parent, false);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
viewHolder.tvName = (TextView) convertView.findViewById(R.id.tvName);
viewHolder.tvTime = (TextView) convertView.findViewById(R.id.tvTime);
viewHolder.tvSize = (TextView) convertView.findViewById(R.id.tvSize);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.posttion = position;
Picture pic = getItem(position);
viewHolder.tvName.setText(pic.getName());
viewHolder.tvTime.setText(pic.getTime());
viewHolder.tvSize.setText(Formatter.formatFileSize(getContext(), pic.getSize()));
Glide.with(getContext()).load(pic.getUrl()).into(viewHolder.imageView);
return convertView;
}
the Item View layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="4dp" >
<ImageView
android:id="@+id/imageView"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/ic_launcher" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:orientation="vertical" >
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/app_name"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="1990年12月23日"
android:textSize="15sp" />
<TextView
android:id="@+id/tvSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="1.0mb"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
the StackTrace:
05-16 05:14:10.578 28356-28376/com.licheetec.bitmaplistviewdemo E/PriorityExecutor﹕ Request threw uncaught throwable
java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:223)
at java.util.concurrent.FutureTask.get(FutureTask.java:82)
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor.afterExecute(FifoPriorityThreadPoolExecutor.java:96)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1084)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:532)
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:442)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
05-16 05:14:10.666 28356-28376/com.licheetec.bitmaplistviewdemo D/dalvikvm﹕ GC_FOR_ALLOC freed 66K, 25% free 44357K/58375K, paused 40ms, total 40ms
05-16 05:14:10.666 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm-heap﹕ Forcing collection of SoftReferences for 14745612-byte allocation
05-16 05:14:10.678 28356-28356/com.licheetec.bitmaplistviewdemo D/OpenGLRenderer﹕ TextureCache::get: create texture(0xb9666368): name, size, mSize = 374, 14745600, 20529712
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo D/dalvikvm﹕ GC_BEFORE_OOM freed 0K, 25% free 44357K/58375K, paused 62ms, total 62ms
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo E/dalvikvm-heap﹕ Out of memory on a 14745612-byte allocation.
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ "fifo-pool-thread-0" prio=5 tid=11 RUNNABLE
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ | group="main" sCount=0 dsCount=0 obj=0xa6d37f10 self=0xb95749e8
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ | sysTid=28376 nice=10 sched=3/0 cgrp=[fopen-error:2] handle=-1184905840
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ | schedstat=( 3580913141 2277818966 1938 ) utm=262 stm=95 core=0
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:532)
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.bitmap.Downsampler.decodeStream(Downsampler.java:329)
05-16 05:14:10.730 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.bitmap.Downsampler.downsampleWithSize(Downsampler.java:220)
05-16 05:14:10.734 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:153)
05-16 05:14:10.734 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:50)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:19)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:39)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:20)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeBitmapWrapper(GifBitmapWrapperResourceDecoder.java:121)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeStream(GifBitmapWrapperResourceDecoder.java:94)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:71)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:61)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:22)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.engine.DecodeJob.decodeFromSourceData(DecodeJob.java:190)
05-16 05:14:10.738 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.engine.DecodeJob.decodeSource(DecodeJob.java:177)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.engine.DecodeJob.decodeFromSource(DecodeJob.java:128)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.engine.EngineRunnable.decodeFromSource(EngineRunnable.java:122)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.engine.EngineRunnable.decode(EngineRunnable.java:101)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.engine.EngineRunnable.run(EngineRunnable.java:58)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at java.lang.Thread.run(Thread.java:856)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
05-16 05:14:10.746 28356-28376/com.licheetec.bitmaplistviewdemo I/dalvikvm﹕ [ 05-16 05:14:10.762 28356:28375 D/dalvikvm ]
GC_FOR_ALLOC freed 14437K, 49% free 30120K/58375K, paused 15ms, total 15ms
05-16 05:14:10.766 28356-28375/com.licheetec.bitmaplistviewdemo I/dalvikvm-heap﹕ Grow heap (frag case) to 43.563MB for 14745612-byte allocation
05-16 05:14:10.770 28356-28376/com.licheetec.bitmaplistviewdemo D/dalvikvm﹕ GC_FOR_ALLOC freed <1K, 24% free 44519K/58375K, paused 5ms, total 5ms
05-16 05:14:10.786 28356-28376/com.licheetec.bitmaplistviewdemo D/skia﹕ --- decoder->decode returned false
2048*1600*4.Also an unrelated tip: it looks like you're using android:hint to have something in the editor preview, take a look at tools:text and friends, also check out the page linked on the bottom of that page for more special attributes.
@TWiStErRob
Thanks for your answer.
I generate a webapp and host it on tomcat in my computer.
There are about 70 pieces of JPG files on the webapp and each image is as big as 2560*1440.
I want to use these super big images to test the performance of Glide.
After reading your answer, I changed the properties of the
<ImageView
android:id="@+id/imageView"
android:layout_width="120dp"
android:layout_height="75dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_launcher" />
Glad it helped. Feel free to ask further questions if you're stuck.
For posterity: fitXY forces Glide to read at full resolution and then let the ImageView handle the distortion (fitXY doesn't keep aspect ratio). If you want to keep distorting the images, you can keep fitXY on the imageView and call centerCrop() or fitCenter() before load(): this will make Glide downsample the image (less memory) before handing it to ImageView for distortion.
Here's a further tip I just noticed: you could also change android:src to tools:src. That way you will save some layout passes (ImageView does a layout on every setImage*() call) and you can skip loading a bitmap (launcher icon when inflating each item) unnecessarily (you'll overwrite it anyway with Glide). The tools attributes are not compiled into the apk, so it's optimal to use them in these situations.
Thanks, A good solution to my problem
Most helpful comment
2048*1600*4.Also an unrelated tip: it looks like you're using
android:hintto have something in the editor preview, take a look attools:textand friends, also check out the page linked on the bottom of that page for more special attributes.