Closed chihung93 closed 6 years ago
What kind of Adapter are you using? Try using Glide.clear() in the destroyItem method of you adapter, in case you're using PagerAdapter..
In MyFragment, I'm using PagerAdapter.
But Activity Parent I'm using FragmentPagerAdapter.
Like this: I have an Activity A, using FragmentPagerAdapter with MyFragment, In My Fragment, I'm using PagerAdapter for images
InnerViewPager viewPager;
BannerSliderAdapter viewPagerAdapter;
viewPagerAdapter = new BannerSliderAdapter(viewPager.getContext(), items, ScreenHelper.getWidthPortrait(), heightOfHeader);
public class BannerSliderAdapter extends PagerAdapter {
public static final String TAG = "BannerSliderAdapter";
private Context context;
// data
private List<String> images = new ArrayList<>();
// for scale
int widthImage = 0;
int heightImage = 0;
private OnItemClickListener listener;
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public BannerSliderAdapter(Context context, List<String> imgs,int widthImage,int heightImage) {
this.context = context;
this.images = imgs;
this.widthImage = widthImage;
this.heightImage = heightImage;
}
@Override
public Object instantiateItem(final ViewGroup collection, final int position) {
final ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
ImageHelper.displayUrl(images.get(position), imageView, widthImage, heightImage);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onItemClicked(collection, imageView, images.get(position), position, TAG);
}
}
});
collection.addView(imageView);
return imageView;
}
@Override
public int getCount() {
return images.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
View itemView = (View)view;
collection.removeView(itemView);
itemView = null;
}
}
1.
int heightOfHeader = (int) ((float) ScreenHelper.getWidthPortrait() / 1.5f);
public class ScreenHelper {
public static int getWidth(){
DisplayMetrics displaymetrics = Resources.getSystem().getDisplayMetrics();
return displaymetrics.widthPixels;
}
public static int getHeight(){
DisplayMetrics displaymetrics = Resources.getSystem().getDisplayMetrics();
return displaymetrics.heightPixels;
}
public static int getWidthPortrait(){
return getWidth() > getHeight() ? getHeight() : getWidth();
}
public static int getHeightPortrait(){
return getWidth() > getHeight() ? getWidth() : getHeight();
}
}
2.How to add attributes (centerCrop) to particular cases in order to easily reuse in ImageHelper?
3.If I clear it in destroyItem, Is it still cached? or it just stops loading.
Thank you so much @gajicm93.
1. 1.1 - I have read some issues about out of memory, so I think the best way is to use an override to avoid out of memory on older devices (low-end devices) instead of automatically. 1.2 - If I use override, does it resize a bitmap automatically?
2. 2.1 - Very useful, I don't know that option before. is it in version 3.x? or just for version 4.0 2.2 - What is the difference between CENTER_CROP native and glide? Can you explain me?
Thanks for patiently explaining to me. @gajicm93
1 + 2.1. Previously, I read a few Glide topics, if I have 1000x1000 images, and override (500,500), it will resize to 500x500 image and not resize anymore. I think that.
2.1 I can't find RequestOptions in version 3.7 in code and Doc.I only saw in version 4.0 Can you give me a link to it in version 3.7? Because version 4.0 it is not really stable to use.
Thank you so much @gajicm93
....
Honestly not sure what toBytes and asBitmap do, I just copied it from Glide documentation.. You probably don't need it..
Thank you so much @gajicm93 again .
@gajicm93 Hello , I read Glide's documentation, I just want to make sure Glide will download the image and save the cache and then scale it ? or save it after scaling?. Because I think it will save the cache first, and will scale later, So when I use the centerCrop attribute of native or glide is the same.
From Doc 3.x
Center crop
Center crop first scales your image down maintaining the original aspect ratio so that one dimension of the image is exactly equal to your target dimensions and the other dimension of the image is greater than your target dimensions. Center crop then crops out the center portion of the image.
Center crop performs the same transformation as Android's ScaleType.CENTER_CROP
I'm also confirming this bug - I moved from Volley to OkHttp3 and from Glide 3 to 4 and found this issue. It happens after I have viewed a number of large images (around 10). The stacktrace is nearly same. I'm also using PageAdapter
.
I didn't encounter this issue while I was using Glide 3 with Volley integration which has been more than 1 year, so I think this is possibly some regression inside Glide 4.0.
I'm using 4.0.0-SNAPSHOT due to the compiler bug of duplicate as()
.
I have tried Glide.with(ImageView).clear(ImageView)
, but the problem persists.
EDIT:
After I fixed a memory leak in my Glide extension, the continuous viewable amount of large images went up to some 20~30 in my stress test, which is perhaps alright.
But still, I think Glide should notified users of the OutOfMemoryError instead of getting neither onLoadFailed
nor onResourceReady
called in this case.
My stacktrace:
06-15 22:23:03.221 29128-29167/me.zhanghai.android.douya E/GlideExecutor: Request threw uncaught throwable
java.lang.OutOfMemoryError: Failed to allocate a 48771084 byte allocation with 5816720 free bytes and 5MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:832)
at android.graphics.Bitmap.createBitmap(Bitmap.java:809)
at android.graphics.Bitmap.createBitmap(Bitmap.java:776)
at com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool.get(LruBitmapPool.java:129)
at com.bumptech.glide.load.resource.bitmap.TransformationUtils.rotateImageExif(TransformationUtils.java:281)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decodeFromWrappedStreams(Downsampler.java:257)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:176)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:134)
at com.bumptech.glide.load.resource.bitmap.ByteBufferBitmapDecoder.decode(ByteBufferBitmapDecoder.java:31)
at com.bumptech.glide.load.resource.bitmap.ByteBufferBitmapDecoder.decode(ByteBufferBitmapDecoder.java:15)
at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:67)
at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:52)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:43)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:56)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:42)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:454)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:447)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:433)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:387)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:356)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:91)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:68)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:71)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:246)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:222)
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.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:347)
This issue has been automatically marked as stale because it has not had activity in the last seven days. It will be closed if no further activity occurs within the next seven days. Thank you for your contributions.
We should be catching OOMs as of 74fcad1340da13ac302994873e076731ab96b8e6 which should be in 4.3.0.
This issue has been automatically marked as stale because it has not had activity in the last seven days. It will be closed if no further activity occurs within the next seven days. Thank you for your contributions.
## Phone : Note 3 At&T OS : Android 5.0
## In My Fragment