Skip to content

Instantly share code, notes, and snippets.

@zsqw123
Last active October 4, 2021 08:34
Show Gist options
  • Save zsqw123/f5b7d776fedaefaa063474b6c7ad2768 to your computer and use it in GitHub Desktop.
Save zsqw123/f5b7d776fedaefaa063474b6c7ad2768 to your computer and use it in GitHub Desktop.
网络监听回调
import android.app.Application
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Handler
import android.os.Looper
import android.util.SparseArray
import androidx.annotation.IntDef
import androidx.core.util.forEach
import androidx.core.util.set
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
/**
* Author zsqw123
* Create by damyjy
* Date 2021/7/12 11:12
*/
class NetCallback private constructor() : ConnectivityManager.NetworkCallback() {
private fun onChange() {
Handler(Looper.getMainLooper()).post { events.forEach { _, v -> v(currentNetState) } }
}
override fun onAvailable(network: Network) {
currentNetState[NetType.NET_AVAILABLE] = true
}
override fun onLost(network: Network) {
currentNetState[NetType.NET_CONNECTED] = false
currentNetState[NetType.NET_WIFI] = false
currentNetState[NetType.NET_CELLULAR] = false
onChange()
}
override fun onUnavailable() {
currentNetState[NetType.NET_AVAILABLE] = false
currentNetState[NetType.NET_CONNECTED] = false
currentNetState[NetType.NET_WIFI] = false
currentNetState[NetType.NET_CELLULAR] = false
onChange()
}
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
currentNetState[NetType.NET_CONNECTED] = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
currentNetState[NetType.NET_WIFI] = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
currentNetState[NetType.NET_CELLULAR] = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
onChange()
}
companion object {
val currentNetState = BooleanArray(4)
private val events = SparseArray<(BooleanArray) -> Unit>()
private var count = 0
private val netRequest by lazy { NetworkRequest.Builder().build() }
private lateinit var connManager: ConnectivityManager
fun init(application: Application) {
connManager = application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connManager.registerNetworkCallback(netRequest, NetCallback())
}
internal fun unregist(index: Int) = events.delete(index)
internal fun regist(callback: (BooleanArray) -> Unit): Int {
events[count] = callback
return count++
}
}
}
@IntDef(NetType.NET_AVAILABLE, NetType.NET_CONNECTED, NetType.NET_WIFI, NetType.NET_CELLULAR)
@Retention(AnnotationRetention.SOURCE)
annotation class NetType {
companion object {
const val NET_AVAILABLE = 0 // 连接可用
const val NET_CONNECTED = 1 // 连接到了 Internet
const val NET_WIFI = 2
const val NET_CELLULAR = 3
}
}
/**
* 自动跟随生命周期的网络回调,需要实现了 LifecycleOwner 接口
* @receiver LifecycleOwner
*/
fun LifecycleOwner.bindNetworkCallback(callback: (BooleanArray) -> Unit) {
var callbackIndex = NetCallback.regist(callback)
lifecycle.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
when (event) {
Lifecycle.Event.ON_START -> callbackIndex = NetCallback.regist(callback)
Lifecycle.Event.ON_STOP -> NetCallback.unregist(callbackIndex)
else -> Unit
}
}
})
}
/**
* 注册全局回调,会返回回调事件的索引,可以用来解除注册回调事件
* @see unregistGlobalNetworkCallback
*/
fun registGlobalNetworkCallback(callback: (BooleanArray) -> Unit): Int = NetCallback.regist(callback)
/**
* 解除回调事件
* @param callbackIndex Int
* @see registGlobalNetworkCallback
*/
fun unregistGlobalNetworkCallback(callbackIndex: Int) = NetCallback.unregist(callbackIndex)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment