Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug report] Conflict between LoadState.complete and LoadState.loading #596

Open
iosephmagno opened this issue Jul 9, 2023 · 7 comments

Comments

@iosephmagno
Copy link

Version

8.0.2

Platforms

Android, iOS

Device Model

iPhone 13 pro iOS16.1

flutter info

Flutter doctor

[✓] Flutter (Channel master, 3.12.0-7.0.pre.22, on macOS 12.6.5 21G531 darwin-arm64, locale en-IT)
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
✗ cmdline-tools component is missing
Run path/to/sdkmanager --install "cmdline-tools;latest"
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run flutter doctor --android-licenses to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 14.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] Connected device (3 available)
[✓] Network resources

How to reproduce?

Sometimes LoadState.completed is invoked when image is still loading and vice-versa.

To reproduce issue, just print loadStateChanged.
Note that issue is consistent but occurs randomly, so it might be required to load the image multiple times to see it.
Any help on this would be much appreciated!

ExtendedImage.network(
        url,    
        fit: BoxFit.contain, 
        loadStateChanged: (imageState) {
          switch (imageState.extendedImageLoadState) {
            case LoadState.loading:
              //debugPrint('ImageMediaView: Image loading');        
              return Container(
                alignment: Alignment.center,
                child: const CircularProgressIndicator(
                  color: Colors.white
                ),
              );
            case LoadState.failed:
              //debugPrint('ImageMediaView: Image failed');
              return Container(
                alignment: Alignment.center,
                child: const CircularProgressIndicator(
                    color: Colors.white
                ),
              );
            case LoadState.completed:
              //debugPrint('ImageMediaView: Image load completed');          
              return imageState.completedWidget;
          }
  ...

Logs

flutter: ImageMediaView: Image loading
flutter: ImageMediaView: Image load completed
flutter: ImageMediaView: Image loading
flutter: ImageMediaView: Image load completed

As per above logs, LoadState.completed is invoked in between of two "LoadState.completed .loading", when image is still loading.

That breaks my logic by which I should run some code only after the image is loaded.
Also, LoadState.loading is sometimes triggered after image is fully loaded, and that breaks my logic as well.

Note: I checked and make sure that the Widget is not rebuild during the process, so it is just ExtentendImage that sometimes consider an image loaded when is still loading and vice-versa.

Example code (optional)

No response

Contact

No response

@zmtzawqlp
Copy link
Member

I couldn't reprduce it at my side. it's better to provide a simple runnable demo. and run on flutter stable branch

@delfme

This comment was marked as outdated.

@iosephmagno
Copy link
Author

Reposting this with my other account not to cause confusion.

I will try, but must inform that Im currently swamped and that might take me some time. Also, we code on flutter master, and if Im not wrong, ExtendedImage doesnt support it yet

@zmtzawqlp
Copy link
Member

any more info about your issue?

@iosephmagno
Copy link
Author

Hello, we had to use this other plugin https://github.com/CHRISTOPANANJICKAL/fast_cached_network_image

It is rudimental, but lets workaround the issue coz state completed is bound to having fully downloaded the file and saved its url to internal hive.

https://github.com/CHRISTOPANANJICKAL/fast_cached_network_image/blob/7d5b23de444a95f7be0e6fa9a4f514df4323096f/lib/src/fast_cached_image.dart#L475

So conflict between loadState.completed and loadState.loading can be avoided by just checking if image isCached()

We will try back again ExtendedImage if you guys will add a similar feature to help workaround issue (which we think is caused by flutter).

@zmtzawqlp
Copy link
Member

i don't think so. The loadState is the ui state, when the page is rebuild, ui should be reload. Even if images are cached in the memory or locally, redrawing them by the flutter engine still takes time, especially for large images. Without a loading interface, this could result in a blank screen。

@delfme
Copy link

delfme commented Nov 17, 2023

Yea indeed it is strange bug. But here is use case:

  1. we fetch remote image and have 2 different conflicting logics that are executed inside loading (there we run methodA) and complete (there we run methodB). Since these methods are conflicting, it is strictly required that methodB inside complete runs after methodA inside loading and methodA never runs after methodB

  2. Unfortunately, loading is sometimes fired a few times after complete, so methodA is sometimes invoked after methodB. That’s why we added a debugPrint to our sample code. Thought that the prints were enough to showcase the issue.

As a workaround, that other plugin allows us to run methodB only if isCached is true and methodA only if isCached is false. So even if loading is fired after complete, methodA wont be executed.

Bug apart, it wouldnt hurt to expose a sync method isCached() also inside ExtendedImage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants