Skip to content

Commit

Permalink
Migration guide for flutter/flutter#49389
Browse files Browse the repository at this point in the history
  • Loading branch information
dnfield committed Jan 29, 2020
1 parent 3dfcd26 commit 490c63e
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
140 changes: 140 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,140 @@
---
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 `obaintsKey`. `ImageProvider` subclasses
should not override `resolve`, but instead should resolve 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.
}
...
}
```

<!-- 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

TBD - will update before landing

## 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 and ImageProvider changes]
* [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

0 comments on commit 490c63e

Please sign in to comment.