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

Migration guide for flutter/flutter#49389 #3622

Merged
merged 6 commits into from
Feb 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions src/docs/release/breaking-changes/image-cache-and-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
title: Changes to ImageCache and ImageProvider
description: ImageCache requires implementers to override containsKey, and
ImageProvider has marked resolve as @nonVirtual
---


## Summary

`ImageCache` now has a method called `containsKey`. `ImageProvider` subclasses
should not override `resolve`, but instead should implement new methods on
`ImageProvider`. These changes were submitted as a single commit to the
framework.

## Description of change

### ContainsKey change

Clients of the `ImageCache`, such as a custom `ImageProvider`, may want to know
if the cache is already tracking an image. Adding the `containsKey` method
allows callers to discover this without calling a method like `putIfAbsent`,
which can trigger an undesired call to `ImageProvider.load`.

The default implementation checks both pending and cached image buckets.

```dart
bool containsKey(Object key) {
return _pendingImages[key] != null || _cache[key] != null;
}
```

### ImageProvider changes

The `ImageProvider.resolve` method does some complicated error handling work
that should not normally be overriden. It also previously did work to load the
image into the image cache, by way of `ImageProvider.obtainKey` and
`ImageProvider.load`. Subclasses had no opportunity to override this behavior
without overriding resolve, and the ability to compose `ImageProvider`s is
limited if multiple `ImageProvider`s expect to override resolve.

To solve this issue, `resolve` is being marked as non-virtual, and two new
protected methods have been added: `createStream` and `resolveStreamForKey`.
These methods allow subclasses to control most of the behavior of `resolve`,
without having to duplicate all the error handling work. It also allows
subclasses that compose `ImageProvider`s to be more confident there will only
be one public entrypoint to the various chained providers.

## Migration guide

### ImageCache change

Before migration, the code would not have an override of `containsKey`.

Code after migration:

<!-- skip -->
```dart
class MyImageCache implements ImageCache {
@override
bool containsKey(Object key) {
// check if your custom cache is tracking this key.
}

...
}
```

### ImageProvider change

Code before the migration:

<!-- skip -->
```dart
class MyImageProvider extends ImageProvider<Object> {
@override
ImageStream resolve(ImageConfiguration configuration) {
// create stream
// set up error handling
// interact with ImageCache
// call obtainKey/load, etc.
}

...
}
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this missing a "Code after the migration:"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Code after the migration:

<!-- skip -->
```dart
class MyImageProvider extends ImageProvider<Object> {
@override
ImageStream createStream(ImageConfiguration configuration) {
// return stream, or just use super.createStream(), which returns a new
// ImageStream.
}

@override
void resolveStreamForKey(
ImageConfiguration configuration,
ImageStream stream,
Object key,
ImageErrorListener handleError,
) {
// Interact with the cache, use the key, potentially call `load`, and
// report any errors back through `handleError`
}

...
}

```

## Timeline

This change was introduced in v1.14.7

## References

API documentation:
* [`ImageCache`]
* [`ImageProvider`]
* [`ScrollAwareImageProvider`]

Relevant issues:
* [Issue #32143]
* [Issue #44510]
* [Issue #48305]
* [Issue #48775]

Relevant PRs:
* [Defer image decoding when scrolling fast #49389]

[Stopped increasing the cache size to accomodate large images]: {{site.github}}/flutter/flutter/pull/47387
[`ImageCache`]: {{site.api}}/flutter/painting/ImageCache-class.html
[`ImageProvider`]: {{site.api}}/flutter/painting/ImageProvider-class.html
[`ScrollAwareImageProvider`]: {{site.api}}/flutter/widgets/ScrollAwareImageProvider-class.html
[Issue #32143]: {{site.github}}/flutter/flutter/issues/32143
[Issue #44510]: {{site.github}}/flutter/flutter/issues/44510
[Issue #48305]: {{site.github}}/flutter/flutter/issues/48305
[Issue #48775]: {{site.github}}/flutter/flutter/issues/48775
[Defer image decoding when scrolling fast #49389]: {{site.github}}/flutter/flutter/pull/49389
2 changes: 2 additions & 0 deletions src/docs/release/breaking-changes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ available:

* [Generic type of ParentDataWidget changed to ParentData][]
* [ImageCache large images][]
* [ImageCache large images][]
* [MouseTracker no longer attaches annotations][]
* [Nullable `CupertinoTheme.brightness`][]
* [Rebuild optimization for OverlayEntries and Routes][]
Expand All @@ -22,6 +23,7 @@ available:
[breaking change policy]: /docs/resources/compatibility
[Generic type of ParentDataWidget changed to ParentData]: /docs/release/breaking-changes/parent-data-widget-generic-type
[ImageCache large images]: /docs/release/breaking-changes/imagecache-large-images
[ImageCache and ImageProvider changes]: /docs/release/breaking-changes/image-cache-and-provider
[MouseTracker no longer attaches annotations]: /docs/release/breaking-changes/mouse-tracker-no-longer-attaches-annotations
[Nullable `CupertinoTheme.brightness`]: /docs/release/breaking-changes/nullable-cupertinothemedata-brightness
[Rebuild optimization for OverlayEntries and Routes]: /docs/release/breaking-changes/overlay-entry-rebuilds
Expand Down