1.TrafficStats
Class that provides network traffic statistics. These statistics include bytes transmitted and received and network packets transmitted and received, over all interfaces, over the mobile interface, and on a per-UID basis.
These statistics may not be available on all platforms. If the statistics are not supported by this device, UNSUPPORTED
will be returned.
简而言之,提供了网络流量数据,这些数据来源于所有设备支持的网卡,包括发送、接收的字节数,还有发送和接收的报文数。某些平台不支持这个接口时,会返回 UNSUPPORTED 的状态。通过 TrafficStats,我们可以分析我们设备当前的上下行速度,对开发一款音视频应用有很大的帮助。
2.代码
import android.net.TrafficStats
import android.os.Handler
import java.text.DecimalFormat
/**
* 用于计算网速
*/
class TrafficStatsRunnable
(private var isTxMode: Boolean, private val uid: Int) : Runnable {
interface TrafficStatsCallback {
fun onResult(speedValue: String)
}
private var lastTimeStamp //前一次的时间
: Long = 0
private var lastTotalBytes //前一次上传的网络数据量
: Long = 0
private val periodMillis: Long = 1000
private var isRunning: Boolean = false
private var callback: TrafficStatsCallback? = null
fun setCallback(callback: TrafficStatsCallback?) {
this.callback = callback
}
private var handler: Handler? = null
private val df: DecimalFormat
init {
handler = Handler()
df = DecimalFormat("#.00")
}
/**
* 复位计数器
*/
fun reset() {
val nowTimeStamp = System.currentTimeMillis()
val nowTotalBytes = if (isTxMode) {
if (TrafficStats.getUidTxBytes(uid) == TrafficStats.UNSUPPORTED.toLong()) 0 else TrafficStats.getTotalTxBytes() shr 10
} else {
if (TrafficStats.getUidRxBytes(uid) == TrafficStats.UNSUPPORTED.toLong()) 0 else TrafficStats.getTotalRxBytes() shr 10 //转为KB
}
lastTimeStamp = nowTimeStamp
lastTotalBytes = nowTotalBytes
}
/**
* 开始计数
*/
fun start(what: Int?) {
isRunning = true
handler?.postDelayed(this, periodMillis)
}
/**
* 停止计数
*/
fun stop() {
isRunning = false
handler?.removeCallbacks(this)
handler = null
}
override fun run() {
if (isRunning) {
val nowTimeStamp = System.currentTimeMillis()
val nowTotalBytes = if (isTxMode) {
if (TrafficStats.getUidTxBytes(uid) == TrafficStats.UNSUPPORTED.toLong()) 0 else TrafficStats.getTotalTxBytes() shr 10
} else {
if (TrafficStats.getUidRxBytes(uid) == TrafficStats.UNSUPPORTED.toLong()) 0 else TrafficStats.getTotalRxBytes() shr 10 //转为KB
}
val diffBytes = nowTotalBytes - lastTotalBytes // 单位:字节B
val speed = diffBytes // 转换为 KB
lastTimeStamp = nowTimeStamp
lastTotalBytes = nowTotalBytes
val strSpeed: String =
if (speed > 1024)
"${df.format(speed / 1024.0)} M/s"
else "$speed KB/s"
callback?.onResult(strSpeed)
handler?.postDelayed(this, periodMillis)
}
}
}
复制代码
3.总结
使用 kotlin 语言,进一步压缩代码,提高代码安全性;声明一个接口 TrafficStatsCallback,用来把当前的网速回调给外部使用;使用 Handler 来实现定时 1s 计算一次;使用位运算符来转换数据单位 B=>KB;从而实现设计目标,该类仅包含了逻辑,并没有包含 View 层,而且兼容了所有平台,因此,可以快速的在项目中进行引用。
评论