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.TrafficStatsimport android.os.Handlerimport 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 层,而且兼容了所有平台,因此,可以快速的在项目中进行引用。
评论