nostra13 / Android-Universal-Image-Loader

Powerful and flexible library for loading, caching and displaying images on Android.
Apache License 2.0
16.78k stars 6.1k forks source link

Mark has been invalidated #394

Closed VenomVendor closed 11 years ago

VenomVendor commented 11 years ago
Start display image task [http://4.bp.blogspot.com/-LEvwF87bbyU/Uicaskm-g6I/AAAAAAAAZ2c/V-WZZAvFg5I/s800/Pesto+Guacamole+500w+0268.jpg_480x782]
Load image from network [http://4.bp.blogspot.com/-LEvwF87bbyU/Uicaskm-g6I/AAAAAAAAZ2c/V-WZZAvFg5I/s800/Pesto+Guacamole+500w+0268.jpg_480x782]
Cache image on disc [http://4.bp.blogspot.com/-LEvwF87bbyU/Uicaskm-g6I/AAAAAAAAZ2c/V-WZZAvFg5I/s800/Pesto+Guacamole+500w+0268.jpg_480x782]
Mark has been invalidated.
java.io.IOException: Mark has been invalidated.
at java.io.BufferedInputStream.reset(BufferedInputStream.java:350)
at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.defineImageSizeAndRotation(BaseImageDecoder.java:88)
at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:69)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:305)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:260)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:129)
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)
  1. Fails to load and cache image, happens only with this image, am using universal-image-loader-1.8.7-snapshot-with-sources.jar.
  2. works buggy with universal-image-loader-1.8.6.jar
    • The same image is downloaded twice with different names, if URL is repeated.
  3. Also noted, when I test with 1.8.6 and switch to 1.8.7 the image which was downloaded twice with different names gets deleted from cache dir
    Config
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
            .threadPriority(Thread.NORM_PRIORITY - 2)
            .denyCacheImageMultipleSizesInMemory()
            .tasksProcessingOrder(QueueProcessingType.LIFO)
            .discCache(new UnlimitedDiscCache(cacheDir))
            .writeDebugLogs() 
            .build();
    // Initialize ImageLoader with configuration.
    ImageLoader.getInstance().init(config);
Options
    options = new DisplayImageOptions.Builder()
        //.showImageOnLoading(R.drawable.ic_stub) //Uncomment for 1.8.7
        .showImageForEmptyUri(R.drawable.ic_empty)
        .showImageOnFail(R.drawable.ic_error)
        .cacheInMemory(false)
        .cacheOnDisc(true)
        .displayer(new RoundedBitmapDisplayer(0))
        .resetViewBeforeLoading(false)
        .imageScaleType(ImageScaleType.EXACTLY)
        .bitmapConfig(Bitmap.Config.RGB_565)
        .build();
Henry84 commented 11 years ago

I have the same problem with local images. For now ,i changed the code like this (in BaseImageDecoder), perhaps could help to someone.

In defineImageSizeAndRotation function , check if mark is supported like this:

    if(imageStream.markSupported())
        imageStream.reset();
    else
        imageStream.close();

And in decode function i did:

            Options decodingOptions = prepareDecodingOptions(imageInfo.imageSize, decodingInfo);
    if(!imageStream.markSupported())
        imageStream = getImageStream(decodingInfo);
    Bitmap decodedBitmap = decodeStream(imageStream, decodingOptions);
sergiiz commented 11 years ago

Have the same problem with images from web. version 1.8.7 snapshot

@Henry84 would you please explain your fix or make it as pull request

bilthon commented 11 years ago

I have the same problem and noticed that it is almost exclusive to .JPG photos. I have a set of PNG files and none of them seems to be affected by it, even if the files are slightly larger. The method pointed out by @Henry84 also did't make a difference to me.

kusraevs commented 11 years ago

I have the same problem with some jpg images on 1.8.7 version. Can't figure out the reason. Please, help. Solution by @Henry84 doesn't work

koral-- commented 11 years ago

I've encountered the same IOException when image from the same URL was fetched multiple times simultaneously. Problem disappeared after eliminating mentioned circumstance by enabling caching. Note: this is not a fix, rather workaround for some cases. I've not investigated what the exact reason is. Mark is invalidated when more bytes than (previously set) read limit have been read from given InputStream.

siyamed commented 11 years ago

I also had to close the stream if I get the exception with stream.reset. Worked for me.

poel commented 11 years ago

@siyamed would you please explain your fix?

siyamed commented 11 years ago

@poel I was already using our own ImageDecoder class which is a simplified version of the one included in the library.

I had to update the following function:

protected ImageFileInfo defineImageSizeAndRotation(InputStream imageStream) throws IOException {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(imageStream, null, options);
    boolean streamClosed = false;
    try{
        imageStream.reset();
    } catch (Throwable t) {
        imageStream.close();
        streamClosed = true;
    }
    return new ImageFileInfo(new ImageSize(options.outWidth, options.outHeight), streamClosed);
}

Then in the main decode function, I made the following change:

public Bitmap decode(ImageDecodingInfo decodingInfo) throws IOException {
    InputStream imageStream = getImageStream(decodingInfo);
    ImageFileInfo imageInfo = defineImageSizeAndRotation(imageStream);

    if(imageInfo.streamClosed) {
        imageStream = getImageStream(decodingInfo);
    }
   ....

As you can see if I get an error during reset function, I mark it, close it, and in the decode function according to that flag I re-create the stream.

scruffyfox commented 11 years ago

I am also experiencing this on 1.8.7 with the image http://i.imgur.com/F4ism2b.jpg

stgogm commented 11 years ago

Funny, never happened before, but today I'm getting this error with some pictures I took with my old phone. I copied them to my new phone and they won't load. There's no problem at all with pictures taken with my current phone's camera.

Old Phone: Samsung GT-I9003L Current Phone: Samsung GT-I8190L

IFDeveloper commented 11 years ago

@siyamed made this fix useless: @nostra13 tryied to increase performance reusing InputStream -> BufferedInputStream, BUT as said in http://code.google.com/p/android/issues/detail?id=57578 article BitmapFactory.decodeStream(bis, null, options); will kill all marks on Buffer and calling reset may create IO EXCEPTIONS in thoes cases (actually as I did ) we can replace InputStream (in DECODE methode) with one of them: https://github.com/bumptech/glide/blob/fdb5f853e615ab46a4f3dea3a46bfca09c75f27a/library/src/com/bumptech/glide/resize/RecyclableBufferedInputStream.java

https://github.com/square/picasso/blob/11b56247226ff02c61ce8ea75f8573943727f48d/picasso/src/main/java/com/squareup/picasso/MarkableInputStream.java

I'm using picasso IS with bufer size of 1024*1024 and for my HTC ONE it's very good. Hope this fix will be applied in next release of main branch =] good luck(6 hours spent to solve total)

nostra13 commented 11 years ago

@FedulovDeveloper Thanks.

stgogm commented 11 years ago

Just cloned the last update. Work perfectly! Thanks @nostra13 and @FedulovDeveloper :-)