Issue 1:
Tested on a real Pixel XL Android 9 (API 28)

image_picker version: 0.4.10

java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/15

D/AndroidRuntime(13697): Shutting down VM
E/AndroidRuntime(13697): FATAL EXCEPTION: main
E/AndroidRuntime(13697): Process: com.example.test, PID: 13697
E/AndroidRuntime(13697): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2342, result=-1, data=Intent { dat=content://com.android.providers.downloads.documents/document/15 flg=0x1 }} to activity {com.example.test/com.example.test.MainActivity}: java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/15
E/AndroidRuntime(13697):	at android.app.ActivityThread.deliverResults(ActivityThread.java:4360)
E/AndroidRuntime(13697):	at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402)
E/AndroidRuntime(13697):	at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
E/AndroidRuntime(13697):	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
E/AndroidRuntime(13697):	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
E/AndroidRuntime(13697):	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
E/AndroidRuntime(13697):	at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(13697):	at android.os.Looper.loop(Looper.java:193)
E/AndroidRuntime(13697):	at android.app.ActivityThread.main(ActivityThread.java:6669)
E/AndroidRuntime(13697):	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(13697):	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/AndroidRuntime(13697):	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
E/AndroidRuntime(13697): Caused by: java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/15
E/AndroidRuntime(13697):	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:165)
E/AndroidRuntime(13697):	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
E/AndroidRuntime(13697):	at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
E/AndroidRuntime(13697):	at android.content.ContentResolver.query(ContentResolver.java:802)
E/AndroidRuntime(13697):	at android.content.ContentResolver.query(ContentResolver.java:752)
E/AndroidRuntime(13697):	at android.content.ContentResolver.query(ContentResolver.java:710)
E/AndroidRuntime(13697):	at io.flutter.plugins.imagepicker.FileUtils.getDataColumn(FileUtils.java:117)
E/AndroidRuntime(13697):	at io.flutter.plugins.imagepicker.FileUtils.getPathFromLocalUri(FileUtils.java:69)
E/AndroidRuntime(13697):	at io.flutter.plugins.imagepicker.FileUtils.getPathFromUri(FileUtils.java:41)
E/AndroidRuntime(13697):	at io.flutter.plugins.imagepicker.ImagePickerDelegate.handleChooseImageResult(ImagePickerDelegate.java:395)
E/AndroidRuntime(13697):	at io.flutter.plugins.imagepicker.ImagePickerDelegate.onActivityResult(ImagePickerDelegate.java:375)
E/AndroidRuntime(13697):	at io.flutter.app.FlutterPluginRegistry.onActivityResult(FlutterPluginRegistry.java:210)
E/AndroidRuntime(13697):	at io.flutter.app.FlutterActivityDelegate.onActivityResult(FlutterActivityDelegate.java:139)
E/AndroidRuntime(13697):	at io.flutter.app.FlutterActivity.onActivityResult(FlutterActivity.java:138)
E/AndroidRuntime(13697):	at android.app.Activity.dispatchActivityResult(Activity.java:7454)
E/AndroidRuntime(13697):	at android.app.ActivityThread.deliverResults(ActivityThread.java:4353)
E/AndroidRuntime(13697):	... 11 more
I/Process (13697): Sending signal. PID: 13697 SIG: 9
Application finished.

[✓] Flutter (Channel dev, v0.8.2, on Mac OS X 10.14 18A384a, locale de-CH)
[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.0)
[✓] Android Studio (version 3.1)
[✓] Connected devices (3 available)

• No issues found!

Issue 2:
I'm working on flutter app that uses a TabView where each view contains a widget with a GlobalKey.

With the latest master channel, the app crashes on switching between the tabs.

However, if I do the following three things, it appears to be very stable.

merge in this PR: #21350

The rationale for the PR is in the PR and its linked issue #11895

remove the following assert in scroll_position.dart, as per issue #18756.

As per my comment in that issue #18756 (comment), it is unclear to me why it is important that pixels != null at this point in the code. I'd love if this assert would read assert(pixels != null, "And here's why it's important..."). Removing it appears to be harmless.

--- a/packages/flutter/lib/src/widgets/scroll_position.dart
+++ b/packages/flutter/lib/src/widgets/scroll_position.dart
@@ -658,7 +658,7 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {

@override
void dispose() {
- assert(pixels != null);
+ // assert(pixels != null);
activity?.dispose(); // it will be null if it got absorbed by another ScrollPosition
_activity = null;
super.dispose();

In Element.updateChild, change the position of checking that a GlobalKey is not being reused by a different widget so that it occurs after the old child widget has had a chance to be deactivated, thus freeing the GlobalKey to be used in the new widget.

See https://stackoverflow.com/questions/49862572/multiple-widgets-used-the-same-globalkey?rq=1 for some more background on this, and an example.

--- a/packages/flutter/lib/src/widgets/framework.dart
+++ b/packages/flutter/lib/src/widgets/framework.dart
@@ -2705,18 +2705,12 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
/// | **child != null** | Old child is removed, returns null. | Old child updated if possible, returns child or new [Element]. |
@protected
Element updateChild(Element child, Widget newWidget, dynamic newSlot) {
- assert(() {
- if (newWidget != null && newWidget.key is GlobalKey) {
- final GlobalKey key = newWidget.key;
- key._debugReserveFor(this);
- }
- return true;
- }());
if (newWidget == null) {
if (child != null)
deactivateChild(child);
return null;
}
+
if (child != null) {
if (child.widget == newWidget) {
if (child.slot != newSlot)
@@ -2737,6 +2731,13 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
deactivateChild(child);
assert(child._parent == null);
}
+ assert(() {
+ if (newWidget.key is GlobalKey) {
+ final GlobalKey key = newWidget.key;
+ key._debugReserveFor(this);
+ }
+ return true;
+ }());
return inflateWidget(newWidget, newSlot);
}

It's okay to move the assert to the end, because it cannot possibly trigger on the other code paths.

Either newWidget == null, so it can't have a GlobalKey anyway. Or child.widget == newWidget so the GlobalKey is already being used by the child. Or (see code below), Widget.canUpdate(child.widget, newWidget) is true, which means that child.widget.key == newWidget.key, according to the rules of being allowed to replace a widget.

if (Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot)
updateSlotForChild(child, newSlot);
child.update(newWidget);
assert(child.widget == newWidget);
assert(() {
child.owner._debugElementWasRebuilt(child);
return true;
}());
return child;
}

Therefore, the only place that needs to have the assert to check we're not using a GlobalKey more than once, is near the end of this method.

I imagine that (1) will land on Master shortly (thanks @dnfield)

I think we need some clarity about why assert(pixels != null) is or isn't important to proceed with (2).

While (3) fixes my problem, and I think I have pretty robust reasoning what bug it fixes and why this is an appropriate fix, I have no idea how to move this forward into a PR. I'd like some advice, or for someone from the core team to take a look.

Thanks