Skip to content

Commit 2b12d8a

Browse files
fix(share_plus): Recover ShareSuccessManager state after error (#2817)
1 parent ca6a39c commit 2b12d8a

File tree

2 files changed

+50
-46
lines changed

2 files changed

+50
-46
lines changed

packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/MethodCallHandler.kt

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,72 +8,68 @@ import java.io.IOException
88
/** Handles the method calls for the plugin. */
99
internal class MethodCallHandler(
1010
private val share: Share,
11-
private val manager: ShareSuccessManager
11+
private val manager: ShareSuccessManager,
1212
) : MethodChannel.MethodCallHandler {
1313

1414
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
15+
expectMapArguments(call)
16+
1517
// The user used a *WithResult method
1618
val isResultRequested = call.method.endsWith("WithResult")
1719
// We don't attempt to return a result if the current API version doesn't support it
18-
val isWithResult = isResultRequested && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
20+
val isWithResult =
21+
isResultRequested && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
1922

20-
when (call.method) {
21-
"shareUri" -> {
22-
expectMapArguments(call)
23-
share.share(
24-
call.argument<Any>("uri") as String,
25-
subject = null,
26-
withResult= false
27-
)
28-
if (!isWithResult) {
29-
result.success(null)
30-
}
31-
}
32-
"share", "shareWithResult" -> {
33-
expectMapArguments(call)
34-
if (isWithResult && !manager.setCallback(result)) return
23+
if (isWithResult && !manager.setCallback(result)) return
3524

36-
// Android does not support showing the share sheet at a particular point on screen.
37-
share.share(
38-
call.argument<Any>("text") as String,
39-
call.argument<Any>("subject") as String?,
40-
isWithResult,
41-
)
25+
try {
26+
when (call.method) {
27+
"shareUri" -> {
28+
share.share(
29+
call.argument<Any>("uri") as String, subject = null, withResult = false
30+
)
31+
success(isWithResult, isResultRequested, result)
32+
}
4233

43-
if (!isWithResult) {
44-
if (isResultRequested) {
45-
result.success("dev.fluttercommunity.plus/share/unavailable")
46-
} else {
47-
result.success(null)
48-
}
34+
"share", "shareWithResult" -> {
35+
share.share(
36+
call.argument<Any>("text") as String,
37+
call.argument<Any>("subject") as String?,
38+
isWithResult,
39+
)
40+
success(isWithResult, isResultRequested, result)
4941
}
50-
}
51-
"shareFiles", "shareFilesWithResult" -> {
52-
expectMapArguments(call)
53-
if (isWithResult && !manager.setCallback(result)) return
5442

55-
// Android does not support showing the share sheet at a particular point on screen.
56-
try {
43+
"shareFiles", "shareFilesWithResult" -> {
5744
share.shareFiles(
5845
call.argument<List<String>>("paths")!!,
5946
call.argument<List<String>?>("mimeTypes"),
6047
call.argument<String?>("text"),
6148
call.argument<String?>("subject"),
6249
isWithResult,
6350
)
64-
65-
if (!isWithResult) {
66-
if (isResultRequested) {
67-
result.success("dev.fluttercommunity.plus/share/unavailable")
68-
} else {
69-
result.success(null)
70-
}
71-
}
72-
} catch (e: IOException) {
73-
result.error("Share failed", e.message, null)
51+
success(isWithResult, isResultRequested, result)
7452
}
53+
54+
else -> result.notImplemented()
55+
}
56+
} catch (e: Throwable) {
57+
manager.clear()
58+
result.error("Share failed", e.message, e)
59+
}
60+
}
61+
62+
private fun success(
63+
isWithResult: Boolean,
64+
isResultRequested: Boolean,
65+
result: MethodChannel.Result
66+
) {
67+
if (!isWithResult) {
68+
if (isResultRequested) {
69+
result.success("dev.fluttercommunity.plus/share/unavailable")
70+
} else {
71+
result.success(null)
7572
}
76-
else -> result.notImplemented()
7773
}
7874
}
7975

packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/ShareSuccessManager.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ internal class ShareSuccessManager(private val context: Context) : ActivityResul
4141
returnResult(RESULT_UNAVAILABLE)
4242
}
4343

44+
/**
45+
* Must be called on error to avoid deadlocking.
46+
*/
47+
fun clear() {
48+
isCalledBack.set(true)
49+
callback = null
50+
}
51+
4452
/**
4553
* Send the result to flutter by invoking the previously set callback.
4654
*/

0 commit comments

Comments
 (0)