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

Images are not loaded after couple of restarts #40

Closed
mig35 opened this issue Apr 20, 2018 · 11 comments
Closed

Images are not loaded after couple of restarts #40

mig35 opened this issue Apr 20, 2018 · 11 comments

Comments

@mig35
Copy link

mig35 commented Apr 20, 2018

I guess this is a cause of the #38 #36 #35

This is a stacktrace of the error:

E/flutter ( 2853): 'package:flutter/src/painting/image_stream.dart': Failed assertion: line 362 pos 12: '_codec != null': is not true.
E/flutter ( 2853): #0      _AssertionError._doThrowNew (dart:core/runtime/liberrors_patch.dart:37:39)
E/flutter ( 2853): #1      _AssertionError._throwNew (dart:core/runtime/liberrors_patch.dart:33:5)
E/flutter ( 2853): #2      MultiFrameImageStreamCompleter._handleCodecReady (package:flutter/src/painting/image_stream.dart)
E/flutter ( 2853): #3      _RootZone.runUnary (dart:async/zone.dart:1381:54)
E/flutter ( 2853): #4      _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
E/flutter ( 2853): #5      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:637:45)
E/flutter ( 2853): #6      Future._propagateToListeners (dart:async/future_impl.dart:666:32)
E/flutter ( 2853): #7      Future._completeError (dart:async/future_impl.dart:489:5)
E/flutter ( 2853): #8      _SyncCompleter._completeError (dart:async/future_impl.dart:55:12)
E/flutter ( 2853): #9      _Completer.completeError (dart:async/future_impl.dart:27:5)
E/flutter ( 2853): #10     CachedNetworkImageProvider._loadAsync (package:cached_network_image/cached_network_image.dart)
E/flutter ( 2853): <asynchronous suspension>
E/flutter ( 2853): #11     CachedNetworkImageProvider.load (package:cached_network_image/cached_network_image.dart:462:16)
E/flutter ( 2853): #12     ImageProvider.resolve.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:265:86)
E/flutter ( 2853): #13     ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:82:22)
E/flutter ( 2853): #14     ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:265:63)
E/flutter ( 2853): #15     SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:38:29)
E/flutter ( 2853): #16     ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:263:30)
E/flutter ( 2853): #17     _ImageProviderResolver.resolve (package:cached_network_image/cached_network_image.dart:193:29)
E/flutter ( 2853): #18     _CachedNetworkImageState._resolveImage (package:cached_network_image/cached_network_image.dart:284:20)
E/flutter ( 2853): #19     _CachedNetworkImageState.didChangeDependencies (package:cached_network_image/cached_network_image.dart:261:5)
E/flutter ( 2853): #20     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3750:12)
E/flutter ( 2853): #21     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3600:5)
E/flutter ( 2853): #22     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #23     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #24     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #25     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #26     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4742:32)
E/flutter ( 2853): #27     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #28     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #29     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #30     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #31     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #32     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #33     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #34     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #35     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3636:16)
E/flutter ( 2853): #36     Element.rebuild (package:flutter/src/widgets/framework.dart:3478:5)
E/flutter ( 2853): #37     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3605:5)
E/flutter ( 2853): #38     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3600:5)
E/flutter ( 2853): #39     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #40     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #41     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #42     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #43     Element.updateChild (package:fl
E/flutter ( 2853): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter ( 2853): NoSuchMethodError: The getter '_value' was called on null.
E/flutter ( 2853): Receiver: null
E/flutter ( 2853): Tried calling: _value
E/flutter ( 2853): #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:46:5)
E/flutter ( 2853): #1      DateTime.difference (dart:core/runtime/libdate_patch.dart:183:54)
E/flutter ( 2853): #2      CacheManager._cleanCache (package:flutter_cache_manager/flutter_cache_manager.dart:129:45)
E/flutter ( 2853): <asynchronous suspension>
E/flutter ( 2853): #3      CacheManager._save (package:flutter_cache_manager/flutter_cache_manager.dart:75:11)
E/flutter ( 2853): <asynchronous suspension>
E/flutter ( 2853): #4      CacheManager.getFile (package:flutter_cache_manager/flutter_cache_manager.dart:243:5)
E/flutter ( 2853): <asynchronous suspension>
E/flutter ( 2853): #5      CachedNetworkImageProvider._loadAsync (package:cached_network_image/cached_network_image.dart:474:35)
E/flutter ( 2853): <asynchronous suspension>
E/flutter ( 2853): #6      CachedNetworkImageProvider.load (package:cached_network_image/cached_network_image.dart:462:16)
E/flutter ( 2853): #7      ImageProvider.resolve.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:265:86)
E/flutter ( 2853): #8      ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:82:22)
E/flutter ( 2853): #9      ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:265:63)
E/flutter ( 2853): #10     SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:38:29)
E/flutter ( 2853): #11     ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:263:30)
E/flutter ( 2853): #12     _ImageProviderResolver.resolve (package:cached_network_image/cached_network_image.dart:193:29)
E/flutter ( 2853): #13     _CachedNetworkImageState._resolveImage (package:cached_network_image/cached_network_image.dart:284:20)
E/flutter ( 2853): #14     _CachedNetworkImageState.didChangeDependencies (package:cached_network_image/cached_network_image.dart:261:5)
E/flutter ( 2853): #15     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3750:12)
E/flutter ( 2853): #16     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3600:5)
E/flutter ( 2853): #17     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #18     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #19     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #20     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #21     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4742:32)
E/flutter ( 2853): #22     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #23     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #24     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #25     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #26     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #27     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #28     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #29     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #30     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3636:16)
E/flutter ( 2853): #31     Element.rebuild (package:flutter/src/widgets/framework.dart:3478:5)
E/flutter ( 2853): #32     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3605:5)
E/flutter ( 2853): #33     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3600:5)
E/flutter ( 2853): #34     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #35     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #36     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4637:14)
E/flutter ( 2853): #37     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
E/flutter ( 2853): #38     Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12)
E/flutter ( 2853): #39     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3636:16)
E/flutter ( 2853): #40     Element.rebuild (package:flutter/src/widgets/framework.dart:3478:5)
E/flutter ( 2853): #41     ComponentElement._firstBuild (package:flutter/src/widgets/f

Also I've found that error happened in this code:

    return new MultiFrameImageStreamCompleter(
        codec: _loadAsync(key).catchError((e) {
          if (errorListener != null) errorListener();
        }),
        scale: key.scale,
        informationCollector: (StringBuffer information) {
          information.writeln('Image provider: $this');
          information.write('Image key: $key');
        });

So in debugger I see that _loadAsync returns with error and then codec becomes null

Then I go deeper and found that error happens in cache_object.dart in method CacheObject.fromMap(String url, Map map) because map is null. Map is null because of CacheManager class and its _getSavedCacheDataFromPreferences method. Inside _keyCacheData we can found an empty string with null map.

To be clear _keyCacheData has "": null inside. I don't know why it is there, but this is the cause.

@jukbot
Copy link

jukbot commented Apr 23, 2018

get the same issue, some image is loaded but the remain images are broken and throw error Failed assertion: line 362 pos 12: '_codec != null': is not true.

@lemonboston
Copy link

We have the same error.

It means in our case that when an image has been tried to load the first time in offline mode, thus resulting in error, it won't load ever again correctly even when reconnected.

As a workaround I have wrapped CachedNetworkImage and show the placeholder 'manually' when there is no connection. Connection is retrieved with InheritedWidget so this wrapper is rebuilt when connection is back, and delegates to CachedNetworkImage.
This of course means we don't show any image in offline mode even if they are cached, so it's not ideal.

@renefloor
Copy link
Collaborator

I am trying to understand what's going wrong, but I don't really understand it..

I tried to breakpoint the code when using an app offline, but it doesn't get past this code in CacheManager.getFile

    if (!_cacheData.containsKey(url)) {
      synchronized(_lock, () {
        if (!_cacheData.containsKey(url)) {
          _cacheData[url] = new CacheObject(url);
        }
      });
    }

I also found that the synchronized doesn't seem to work the way I expected and that the singleton design seems to be broken. I could not find any sources on how to make a Singleton when the initialization phase needs an await (is asynchronous).

I also suspect that the synchronized might be broken in dart 2.0.

@mig35
Copy link
Author

mig35 commented Apr 26, 2018

@renefloor you can create a quick fix my checking map for null in your code before pushing to CacheObject

@Cyan101
Copy link

Cyan101 commented Apr 26, 2018

@lemonboston any chance you can share or PR?

@renefloor
Copy link
Collaborator

Could you check whether this is fixed in 0.4.1? I did multiple improvements, so I am not sure whether this case is fixed.

@jonasbark
Copy link

didn't see that happening again with 0.4.1

@lemonboston
Copy link

lemonboston commented May 2, 2018

I don't see the exception with 0.4.1 either, although the issue with these steps still happens:

  • disconnect from network
  • open a screen with an image (doesn't load)
  • go back from screen, reconnect, open screen again
  • actual: image not loaded, expected: loads

But if I close and restart the app, then that particular image is loaded correctly (I don't know if that was the case with 0.4.0 as well or not).

@Cyan101 my workaround was not a fix for this library, just guarding CachedNetworkImageWidget in a way that it's not shown when there is no network. I used this lib for checking connection:
https://pub.dartlang.org/packages/connectivity

@renefloor
Copy link
Collaborator

@lemonboston that is indeed still a problem. See also the conversation in https://github.com/renefloor/flutter_cache_manager/issues/9 and issue #41.

@pavel-ismailov
Copy link

@renefloor

Why is that closed?
Am I understood right that you consider the bud related to Flutter sources flutter_cache_manager, not your library?

@kadaha
Copy link

kadaha commented Aug 3, 2018

Here is how i made it work for now

try to add this to the main or before :

import 'package:flutter_cache_manager/flutter_cache_manager.dart';
void main() async {
  CacheManager.getInstance();
.....
}

This will init the cache manager if its null so _cacheData will not be null :

static Future getInstance() async {
if (_instance == null) {
await synchronized(_lock, () async {
if (_instance == null) {
instance = new CacheManager.();
await _instance._init(); <----------------------------------
}
});
}
return _instance;
}

CacheManager._();

SharedPreferences _prefs;
Map<String, CacheObject> _cacheData;<-------------------------------(Not initialized )
DateTime lastCacheClean;

static Object _lock = new Object();

///Shared preferences is used to keep track of the information about the files
_init() async {
_prefs = await SharedPreferences.getInstance();
_getSavedCacheDataFromPreferences();<---------------------------------------------
_getLastCleanTimestampFromPreferences();
}

_getSavedCacheDataFromPreferences() {
//get saved cache data from shared prefs
var jsonCacheString = _prefs.getString(_keyCacheData);
_cacheData = new Map(); <------------------------------------------------------ (initialized)
if (jsonCacheString != null) {
Map jsonCache = const JsonDecoder().convert(jsonCacheString);
jsonCache.forEach((key, data) {
if (data != null) {
_cacheData[key] = new CacheObject.fromMap(key, data);
}
});
}
}

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

8 participants