首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 在非 Activity 類中使用 ConnectivityManager 檢測網絡狀態

     編輯:程式設計綜合問答

ConnectivityManager 是 Android 核心系統服務,需通過 Context.getSystemService() 獲取。在 Activity 中可直接呼叫 getSystemService(),但在普通 Java 類(工具類、Presenter、ViewModel 等)中無法直接調用,必須傳入 Context 對象。

錯誤場景:普通類中直接調用

public class NetUtils {
    // ❌ 編譯錯誤:無法解析 getSystemService
    public static boolean isConnected() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        // ...
    }
}

正確做法:方法參數傳遞 Context

public class NetUtils {
    // ✅ 接收 Context 參數
    public static boolean isConnected(Context context) {
        // 建議檢查 context 非空
        if (context == null) return false;
        
        ConnectivityManager cm = (ConnectivityManager) 
            context.getSystemService(Context.CONNECTIVITY_SERVICE);
        
        if (cm == null) return false;
        
        // API 29+ 建議使用 NetworkCapabilities
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            return capabilities != null && 
                   (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
        } else {
            // 舊版 API
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        }
    }
}

調用示例

// 在 Activity/Fragment 中
if (NetUtils.isConnected(this)) { ... }

// 在 ViewModel 中(需傳入 Application Context)
if (NetUtils.isConnected(getApplication())) { ... }

// 在非 UI 線程(傳入 Application Context 避免洩漏)
if (NetUtils.isConnected(MyApplication.getInstance())) { ... }

最佳實踐建議

  1. 傳 Application Context:長生命週期對象(單例、Service、靜態工具類)務必使用 context.getApplicationContext(),避免持有 Activity 導致記憶體洩漏。
  2. 權限聲明:AndroidManifest.xml 需添加 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />。
  3. 封裝為 LiveData/Flow:現代架構建議將網絡狀態封裝為可觀察對象,UI 自動響應變化。

進階:監聽網絡變化

// API 24+ 使用 NetworkCallback
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(@NonNull Network network) {
        // 網絡可用
    }
    @Override
    public void onLost(@NonNull Network network) {
        // 網絡斷開
    }
});

掌握 Context 傳遞原理,不僅解決 ConnectivityManager 問題,更是 Android 開發中區分「上下文類型與生命週期」的核心功課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved