【问题标题】:Listening to network changes using Connectivity Manager使用 Connectivity Manager 监听网络变化
【发布时间】:2020-12-15 10:11:17
【问题描述】:

我正在尝试使用 conenctivityManager 的方法 registerDefaultNetworkCallback() 来监听网络变化 使用来自answer的以下代码

     val connectivityManager = cotnext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        connectivityManager?.let {
            it.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    //take action when network connection is gained
                }
                override fun onLost(network: Network) {
                    //take action when network connection is lost
                }
            })
        }

但是我对这个方法有几个问题:

  1. 如果手机连接了wifi但wifi没有连接到互联网怎么办
  2. 在方法文档中,我读到了我不明白的内容,究竟什么时候会达到限制?如果回调被调用 100 次,那么会抛出异常吗?以及如何处理?

为避免由于应用泄漏回调导致的性能问题,系统会将未完成请求的数量限制为每个应用 100 个(由其 UID 标识),并与此方法的所有变体、requestNetwork 以及 ConnectivityDiagnosticsManager.registerConnectivityDiagnosticsCallback 共享。使用此方法请求网络将计入此限制。如果超过此限制,将引发异常。为避免遇到此问题并节省资源,请确保使用 unregisterNetworkCallback(ConnectivityManager.NetworkCallback) 取消注册回调。

【问题讨论】:

    标签: android kotlin android-connectivitymanager


    【解决方案1】:
    1. 手机连接wifi但是wifi没有连接怎么办 上网

    答案,这个方法会返回false

    1. 在方法文档中,我阅读了我没有阅读的内容 明白,到底什么时候会达到极限?如果回调是 调用 100 次然后会抛出异常?以及如何处理 这个?

    我认为这意味着如果您不能注册超过 100 个回调

    【讨论】:

    • 我也不确定“100 个未完成的请求”是什么意思,他们应该说得更清楚。但是是的,看看它抛出的异常可能意味着 100 个注册
    • 有 100 个注册听众。如果你计算你的听众,当你注册的听众达到 100 时,你会崩溃(TooManyRequestsException)。
    【解决方案2】:

    首先,添加 ConnectivityReceiver 类:

    class ConnectivityReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (connectivityReceiverListener != null) {
                connectivityReceiverListener!!.onNetworkConnectionChanged(
                    isConnectedOrConnecting(
                        context
                    )
                )
            }
        }
    
        private fun isConnectedOrConnecting(context: Context): Boolean {
            val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    
            if (cm != null) {
                if (Build.VERSION.SDK_INT < 23) {
                    val ni = cm.activeNetworkInfo
                    if (ni != null) {
                        return ni.isConnected && (ni.type == ConnectivityManager.TYPE_WIFI || ni.type == ConnectivityManager.TYPE_MOBILE)
                    }
                } else {
                    val n = cm.activeNetwork
                    if (n != null) {
                        val nc = cm.getNetworkCapabilities(n)
                        return nc!!.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc!!.hasTransport(
                            NetworkCapabilities.TRANSPORT_WIFI
                        )
                    }
                }
            }
            return false
        }
    
        interface ConnectivityReceiverListener {
            fun onNetworkConnectionChanged(isConnected: Boolean)
        }
    
        companion object {
            var connectivityReceiverListener: ConnectivityReceiverListener? = null
        }
    
    }
    

    然后在你的 BaseActivityMainActivity 添加这些行:

     abstract class BaseActivity:AppCompatActivity(), 
          ConnectivityReceiver.ConnectivityReceiverListener {
    
    var receiver: ConnectivityReceiver? = null
    
    override fun onResume() {
            super.onResume()
            try {
                receiver = ConnectivityReceiver()
                registerReceiver(
                    receiver!!,
                    IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
                )
                connectivityReceiverListener = this
            } catch (ex: Exception) {
                //Timber.d("Base ex ${ex.localizedMessage}")
            }
    
        }
    
        override fun onPause() {
            try {
                unregisterReceiver(receiver!!)
                receiver = null
    
            } catch (ex: Exception) {
            }
            super.onPause()
    
        }
    
     override fun onNetworkConnectionChanged(isConnected: Boolean) {
            showMessage(isConnected)
        }
    
    
    private fun showMessage(isConnected: Boolean) {
        try {
            if (!isConnected) {
               Log.d("Connection state"," disconnected")
            } else {
                Log.d("Connection state"," connected")
            }
        } catch (ex: Exception) {
           
        }
    } 
    }
    

    您应该在 OnResume 方法中注册接收器并在 OnPause 方法中取消注册它

    【讨论】:

    • 您的答案中有不推荐使用的代码,例如CONNECTIVITY_ACTION 和其他内容
    • 请看这个链接:proandroiddev.com/…
    • 我阅读了教程,它使用与我的问题相同的代码,但没有回答我上面的问题。
    猜你喜欢
    • 1970-01-01
    • 2016-05-15
    • 2022-07-21
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    相关资源
    最近更新 更多