diff --git a/network/android/src/main/java/com/capacitorjs/plugins/network/Network.java b/network/android/src/main/java/com/capacitorjs/plugins/network/Network.java index 8f8842feec..da88128eed 100644 --- a/network/android/src/main/java/com/capacitorjs/plugins/network/Network.java +++ b/network/android/src/main/java/com/capacitorjs/plugins/network/Network.java @@ -75,7 +75,7 @@ public NetworkStatus getNetworkStatus() { NetworkStatus networkStatus = new NetworkStatus(); if (this.connectivityManager != null) { android.net.Network activeNetwork = this.connectivityManager.getActiveNetwork(); - NetworkCapabilities capabilities = this.connectivityManager.getNetworkCapabilities(this.connectivityManager.getActiveNetwork()); + NetworkCapabilities capabilities = this.connectivityManager.getNetworkCapabilities(activeNetwork); if (activeNetwork != null && capabilities != null) { networkStatus.connected = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) && diff --git a/network/android/src/main/java/com/capacitorjs/plugins/network/NetworkPlugin.java b/network/android/src/main/java/com/capacitorjs/plugins/network/NetworkPlugin.java index d1fe63ef8d..194f1df30a 100644 --- a/network/android/src/main/java/com/capacitorjs/plugins/network/NetworkPlugin.java +++ b/network/android/src/main/java/com/capacitorjs/plugins/network/NetworkPlugin.java @@ -52,33 +52,41 @@ public void getStatus(PluginCall call) { } /** - * Register the IntentReceiver on resume + * Register the network callback on resume. + * The ConnectivityManager calls are binder IPCs that can block for a long time, so they run + * on the plugin thread instead of the main thread to avoid ANRs. The plugin thread is a single + * serial thread, so this work stays ordered with handleOnPause and with plugin method calls. */ @Override protected void handleOnResume() { - implementation.startMonitoring(); - NetworkStatus afterPauseNetworkStatus = implementation.getNetworkStatus(); - if ( - prePauseNetworkStatus != null && - !afterPauseNetworkStatus.connected && - (prePauseNetworkStatus.connected || afterPauseNetworkStatus.connectionType != prePauseNetworkStatus.connectionType) - ) { - Log.d( - "Capacitor/NetworkPlugin", - "Detected pre-pause and after-pause network status mismatch. Updating network status and notifying listeners." - ); - this.updateNetworkStatus(); - } - this.prePauseNetworkStatus = null; + getBridge().execute(() -> { + implementation.startMonitoring(); + NetworkStatus afterPauseNetworkStatus = implementation.getNetworkStatus(); + if ( + prePauseNetworkStatus != null && + !afterPauseNetworkStatus.connected && + (prePauseNetworkStatus.connected || afterPauseNetworkStatus.connectionType != prePauseNetworkStatus.connectionType) + ) { + Log.d( + "Capacitor/NetworkPlugin", + "Detected pre-pause and after-pause network status mismatch. Updating network status and notifying listeners." + ); + this.updateNetworkStatus(); + } + this.prePauseNetworkStatus = null; + }); } /** - * Unregister the IntentReceiver on pause to avoid leaking it + * Unregister the network callback on pause to avoid leaking it. + * Runs on the plugin thread for the same reason as handleOnResume. */ @Override protected void handleOnPause() { - this.prePauseNetworkStatus = implementation.getNetworkStatus(); - implementation.stopMonitoring(); + getBridge().execute(() -> { + this.prePauseNetworkStatus = implementation.getNetworkStatus(); + implementation.stopMonitoring(); + }); } private void updateNetworkStatus() {