bug(network): Android networkStatusChange re-queries the active network inside callbacks and fires on every capability change
評価
- 難易度
- 4/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 25/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 領域
- mobile, networking
調査の方向性
Start with network/android/src/main/java/com/getcapacitorjs/plugins/network/Network.java and NetworkPlugin.java, especially the callback, status calculation, and lifecycle registration methods linked in the issue. Review the open linked pull request #2622 and compare its changes with the expected behavior. Done means callback arguments provide status, duplicate events are suppressed, monitoring starts on load, and registration is safe across lifecycle calls.
索引モデルが issue の本文から書いたものです。
説明
Bug Report
Plugin(s)
@capacitor/network 8.0.1 (same code on main at 87c0bb8 and in 9.0.0-alpha.2)
Capacitor Version
@capacitor/core: 8.5.3
@capacitor/android: 8.5.3
@capacitor/network: 8.0.1
compileSdk 36, minSdk 24
Platform(s)
Android
Current Behavior
-
The network callback ignores its arguments and re-queries the active network.
onCapabilitiesChangeddrops theNetworkCapabilitiesit receives (Network.java:29-32);NetworkPluginthen callsgetNetworkStatus()(NetworkPlugin.java:84-86), which callsgetActiveNetwork()twice andgetNetworkCapabilities()(Network.java:77-78). TheConnectivityManager.NetworkCallbackreference says not to call synchronousConnectivityManagermethods from inside callbacks, because the result can be out of date relative to the callback; the arguments passed in are the source of truth.onLostalso emitsnonefor any lost network without checking it was the current default (Network.java:22-26, NetworkPlugin.java:25-29). -
Every capability change emits an event, even when nothing reported changed. There is no comparison with the last emitted status (NetworkPlugin.java:84-86).
onCapabilitiesChangedfires for signal strength and link bandwidth updates, so listeners get repeatednetworkStatusChangeevents with an identical{ connected, connectionType }. Registering the callback on each resume also delivers an immediate callback, so every resume emits too. This was acknowledged as a bug in ionic-team/capacitor#1492 (labeledtype: bug, diagnosed as the onResume registration) and reported again in #1014 and #2138; all were closed in backlog cleanup without a fix. -
No events before the first resume.
load()only sets the listener (NetworkPlugin.java:22-35);startMonitoring()is only called fromhandleOnResume(NetworkPlugin.java:59). -
Unguarded register/unregister.
startMonitoring/stopMonitoringcallregisterDefaultNetworkCallback/unregisterNetworkCallbackwith no registered-state check (Network.java:114-123). Android throwsIllegalArgumentExceptionwhen unregistering a callback that isn't registered or registering one twice, so a pause without a preceding resume, or a repeated pause, can crash. Not reproduced; possibly related to #2107.
Expected Behavior
- Status in callbacks comes from the callback's own
Network/NetworkCapabilities. networkStatusChangefires only whenconnectedorconnectionTypeactually changes.- Monitoring starts when the plugin loads.
- Register/unregister can't throw on lifecycle ordering.
Code Reproduction
No sample app needed beyond the plugin's own example:
import { Network } from '@capacitor/network';
Network.addListener('networkStatusChange', s => console.log('event', Date.now(), JSON.stringify(s)));
- Run on a device connected to Wi-Fi.
- Walk away from the router and back (or move between rooms) so the signal level changes, without disconnecting.
- Logcat shows repeated
networkStatusChangeevents, each with{"connected":true,"connectionType":"wifi"}. - Background and foreground the app (open the notification shade, a permission dialog, or the app switcher): one more identical event per resume.
Other Technical Details
A PR follows. It keeps connected = VALIDATED && INTERNET and keeps getStatus() querying the active network as today. It doesn't change the public API.
Related open items, not duplicated by the PR: #2563 / #2606 (ANR from ConnectivityManager calls on the main thread in handleOnResume), #2564 (captive portal / limited state), #2555 (metered / constrained flags).
Additional Context
Prior reports: ionic-team/capacitor#1492, #1014, #2138, #2107.
- 主要言語
- Java
- スター
- 687
- フォーク
- 691
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
ionic-team/capacitor-plugins のほかの issue
-
triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
ionic-team/capacitor-plugins#2616 ·
-
[@capacitor/app] iOS: 'Expression implicitly coerced from String? to Any' warning in getAppLanguageオープンtriage
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
ionic-team/capacitor-plugins#2604 ·
-
bug(network): iOS getStatus() returns the last reachability callback value instead of reading current flags対応中かも @kcjonson が 1 日前に担当しました。 オープンplatform: ios
難易度 2/5 1〜3時間 初心者へのやさしさ 35/100
ionic-team/capacitor-plugins#2620 ·
-
platform: android platform: ios
難易度 5/5 1週間以上 初心者へのやさしさ 24/100
ionic-team/capacitor-plugins#2619 ·
-
triage
難易度 3/5 1〜2日 初心者へのやさしさ 66/100
ionic-team/capacitor-plugins#2615 ·
ionic-team/capacitor-plugins の issue をすべて見る
似ている issue
-
dev/release: verify-release-candidate.sh runs 0 Java tests with Debian's Maven対応中かも @kou が今日担当しました。 オープンType: bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
apache/arrow-adbc#4947 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
checkstyle/checkstyle#22153 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 79/100
メンテナーはふだん 1 日以内に返信
-
Documentation Needs Triage
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
frankframework/frankframework#11908 ·
メンテナーはふだん 1 日以内に返信