Closed cpraehaus closed 1 year ago
The problem is that the Xamarin.Essentials.Connectivity.EssentialsNetworkCallback
instance is being collected when Java still wants to invoke methods on it.
This suggests a premature .Dispose()
call or a GC bug.
Please collect and provide GREF logs; see also:
With a quick (quick!) code review, I suspect that the "problem" is actually networkCallback?.Dispose()
:
If we assume a multithreaded environment, it is possible that while "Thead 1" calls Connectivity.UnregisterNetworkCallback()
+ ConnectivityManager.UnregisterNetworkCallback()
+ EssentialsNetworkCallback.Dispose()
, another Java thread may attempt to attempt to invoke networkCallback
methods after the dispose:
ConnectivityManager.NetworkCallback cb = /* something that gets the EssentialsNetworkCallback instance */
Connectivity.UnregisterNetworkCallback()
(doesn't impact (1))ConnectivityManager.UnregisterNetworkCallback(networkCallback)
(doesn't impact (1))networkCallback.Dispose()
(removes association between cb
and networkCallback
)cb.onUnavailable()
(or any other NetworkCallback
method)At this point there is no association between the Java instance and the C# instance, so Xamarin.Android attempts to create one via the (IntPtr, JniHandleOwnership)
constructor, which doesn't exist, which results in the reported JavaProxyThrowable
+ NotSupportedException
.
If this is the case, the fix is to not call .Dispose()
, and simply remove this line:
@jfversluis could you please take a look?
Will the dispose removal be committed to Xamarin Essentials?
Description
Recently we experienced app crashes in our app on Android after we upgraded to XE 1.7.2. Probably due to #1568 . In our app we subscribe and unsubscribe to
Connectivity.ConnectivityChanged
event a few times during startup (not often). In some cases we observe app crashes where the app terminates with JavaLocationException shortly after starting (when the connectivity events are subscribed).We think the reason is that by unsubscribing the event Connectivity stops and removes the listeners and disposes
EssentialsNetworkCallback
. However there is a (not so low) chance that callback invocation is already scheduled while managed wrapperEssentialsNetworkCallback
is disposed (even if listener was currectly unregistered before). In this case the Java native/JNI domain cannot invoke the callback anymore causing the exception shown below which terminates the app.Note that other XE modules like Magnetometer might also be affected by the same problem, see for example #1272 .
This is the exception we see (note that the stack trace might be slightly different depending on which network event is being delivered):
Here we see the course of events during a local repro:
Steps to Reproduce
Expected Behavior
ConnectivityChanged can be subscribed/unsubscribed multiple times without problems.
Actual Behavior
App crashes when ConnectivityChanged is subscribed/unsubscribed multiple times.
Basic Information
Screenshots
None
Reproduction Link
On request