Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit c153033

Browse files
jason-simmonsChris Yang
authored andcommitted
Return image picker method call results on the platform thread (#1585)
The MediaScanConnection.scanFile callback is invoked on a background thread. However, MethodChannel results must be provided on the platform thread. Fixes flutter/flutter#32315
1 parent a7c074c commit c153033

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

packages/image_picker/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.6.0+3
2+
3+
* Android: fixed assertion failures due to reply messages that were sent on the wrong thread.
4+
15
## 0.6.0+2
26

37
* Android: images are saved with their real extension instead of always using `.jpg`.

packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import android.app.Application;
99
import android.os.Bundle;
1010
import android.os.Environment;
11+
import android.os.Handler;
12+
import android.os.Looper;
1113
import androidx.annotation.VisibleForTesting;
1214
import io.flutter.plugin.common.MethodCall;
1315
import io.flutter.plugin.common.MethodChannel;
@@ -94,12 +96,58 @@ public void onActivityStopped(Activity activity) {}
9496
}
9597
}
9698

99+
// MethodChannel.Result wrapper that responds on the platform thread.
100+
private static class MethodResultWrapper implements MethodChannel.Result {
101+
private MethodChannel.Result methodResult;
102+
private Handler handler;
103+
104+
MethodResultWrapper(MethodChannel.Result result) {
105+
methodResult = result;
106+
handler = new Handler(Looper.getMainLooper());
107+
}
108+
109+
@Override
110+
public void success(final Object result) {
111+
handler.post(
112+
new Runnable() {
113+
@Override
114+
public void run() {
115+
methodResult.success(result);
116+
}
117+
});
118+
}
119+
120+
@Override
121+
public void error(
122+
final String errorCode, final String errorMessage, final Object errorDetails) {
123+
handler.post(
124+
new Runnable() {
125+
@Override
126+
public void run() {
127+
methodResult.error(errorCode, errorMessage, errorDetails);
128+
}
129+
});
130+
}
131+
132+
@Override
133+
public void notImplemented() {
134+
handler.post(
135+
new Runnable() {
136+
@Override
137+
public void run() {
138+
methodResult.notImplemented();
139+
}
140+
});
141+
}
142+
}
143+
97144
@Override
98-
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
145+
public void onMethodCall(MethodCall call, MethodChannel.Result rawResult) {
99146
if (registrar.activity() == null) {
100-
result.error("no_activity", "image_picker plugin requires a foreground activity.", null);
147+
rawResult.error("no_activity", "image_picker plugin requires a foreground activity.", null);
101148
return;
102149
}
150+
MethodChannel.Result result = new MethodResultWrapper(rawResult);
103151
int imageSource;
104152
switch (call.method) {
105153
case METHOD_CALL_IMAGE:

packages/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.flutter.plugins.imagepicker;
22

33
import static org.junit.Assert.assertTrue;
4+
import static org.mockito.ArgumentMatchers.any;
5+
import static org.mockito.ArgumentMatchers.eq;
46
import static org.mockito.Mockito.verify;
57
import static org.mockito.Mockito.verifyZeroInteractions;
68
import static org.mockito.Mockito.when;
@@ -81,7 +83,7 @@ public void onMethodCall_WhenSourceIsGallery_InvokesChooseImageFromGallery() {
8183

8284
plugin.onMethodCall(call, mockResult);
8385

84-
verify(mockImagePickerDelegate).chooseImageFromGallery(call, mockResult);
86+
verify(mockImagePickerDelegate).chooseImageFromGallery(eq(call), any());
8587
verifyZeroInteractions(mockResult);
8688
}
8789

@@ -92,7 +94,7 @@ public void onMethodCall_WhenSourceIsCamera_InvokesTakeImageWithCamera() {
9294

9395
plugin.onMethodCall(call, mockResult);
9496

95-
verify(mockImagePickerDelegate).takeImageWithCamera(call, mockResult);
97+
verify(mockImagePickerDelegate).takeImageWithCamera(eq(call), any());
9698
verifyZeroInteractions(mockResult);
9799
}
98100

packages/image_picker/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ authors:
55
- Flutter Team <[email protected]>
66
- Rhodes Davis Jr. <[email protected]>
77
homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker
8-
version: 0.6.0+2
8+
version: 0.6.0+3
99

1010
flutter:
1111
plugin:

0 commit comments

Comments
 (0)