Android流量統計

來源:互聯網
上載者:User

標籤:擷取   使用   現在   com   log   turn   size   如何使用   adb shell   

項目中需要對Android裝置進行流量統計來進行資費結算,所以對Android裝置流量統計進行了一些調研。發現流量統計主流上有兩種方式

  • 使用系統統計類TrafficStats擷取
  • 通過系統檔案解析讀取
TrafficStats
  • static long getMobileRxBytes() //擷取通過Mobile串連收到的位元組總數,不包含WiFi
  • static long getMobileRxPackets() //擷取Mobile串連收到的資料包總數
  • static long getMobileTxBytes() //Mobile發送的總位元組數
  • static long getMobileTxPackets() //Mobile發送的總資料包數
  • static long getTotalRxBytes() //擷取總的接受位元組數,包含Mobile和WiFi等
  • static long getTotalRxPackets() //總的接受資料包數,包含Mobile和WiFi等
  • static long getTotalTxBytes() //總的發送位元組數,包含Mobile和WiFi等
  • static long getTotalTxPackets() //發送的總資料包數,包含Mobile和WiFi等
  • static long getUidRxBytes(int uid) //擷取某個網路UID的接受位元組數
  • static long getUidTxBytes(int uid) //擷取某個網路UID的發送位元組數

這些方法 擷取到的流量資料都是從手機上次開機到當前的流量使用方式,這個沒關係,我們可以監聽手機的開機和關機。關機的時候(或者每間隔一段時間) 將資料都儲存起來,下次開機後通過以上方法擷取到的資料在疊加上.

但是這些方法裡面,只能我發現在這些方法裡,缺少我最需要的那個方法,我想擷取某個app接受和發送的2G/3G流量,不包含wifi,這些API無法滿足該需求。

於是乎,便從系統檔案的解析上著手吧

/proc/net/xt_qtaguid/stats格式

/proc/net/xt_qtaguid/stats內包含著各個app使用流量的情況,先來簡單看一下這個檔案的內容

這輸出內容整體是一個表結構,首先我們需要看一下表中各欄欄位代表什麼

  • idx : 序號
  • iface : 代表流量類型(rmnet表示2G/3G, wlan表示Wifi流量,lo表示本地流量)
  • acct_tag_hex :線程標記(用於區分單個應用內不同模組/線程的流量)
  • uid_tag_int : 應用uid,據此判斷是否是某應用統計的流量資料
  • cnt_set : 應用前後標誌位:1:前台, 0:後台
  • rx_btyes : receive bytes 接受到的位元組數
  • rx_packets : 接收到的任務包數
  • tx_bytes : transmit bytes 發送的總位元組數
  • tx_packets : 發送的總包數
  • rx_tcp_types : 接收到的tcp位元組數
  • rx_tcp_packets : 接收到的tcp包數
  • rx_udp_bytes : 接收到的udp位元組數
  • rx_udp_packets : 接收到的udp包數
  • rx_other_bytes : 接收到的其他類型位元組數
  • rx_other_packets : 接收到的其他類型包數
  • tx_tcp_bytes : 發送的tcp位元組數
  • tx_tcp_packets : 發送的tcp包數
  • tx_udp_bytes : 發送的udp位元組數
  • tx_udp_packets : 發送的udp包數
  • tx_other_bytes : 發送的其他類型位元組數
  • tx_other_packets : 發送的其他類型包數

可以看到,用檔案解析的方式擷取流量可以獲得比直接使用acct_tag_hex要豐富的多的資訊,包括區分WIFI和移動網路,區分應用內不同模組功能流量,前後台流量等。

使用shell命令來查看進程流量

接下來說明下uid_tag_int這個欄位

pid:Processid(進程id)
擷取pid的shell命令:

grep com.car.tencent

  • uid:每個應用程式一個uid(如果一個app擁有兩個進程,則有兩個不同pid,但兩個pid對應的uid是相同的)
    根據pid擷取uid

    adb shell cat /proc/1643/status
  • 根據uid擷取流量

    adb shell cat /proc/net/xt_qtaguid/stats | grep uid
如何使用代碼解析/proc/net/xt_qtaguid/stats檔案
static const char *QTAGUID_UID_STATS = "/proc/net/xt_qtaguid/stats";struct Stats {    uint64_t rxBytes;    uint64_t rxPackets;    uint64_t txBytes;    uint64_t txPackets;    uint64_t tcpRxPackets;    uint64_t tcpTxPackets;};static int parseUidStats(const uint32_t uid, struct Stats *stats) {    FILE *fp = fopen(QTAGUID_UID_STATS, "r");    if (fp == NULL) {        return -1;    }    char buffer[384];    char iface[32];    uint32_t idx, cur_uid, set;    uint64_t tag, rxBytes, rxPackets, txBytes, txPackets;    while (fgets(buffer, sizeof(buffer), fp) != NULL) {        if (sscanf(buffer,                   "%" SCNu32 " %31s 0x%" SCNx64 " %u %u %" SCNu64 " %" SCNu64                           " %" SCNu64 " %" SCNu64 "",                   &idx, iface, &tag, &cur_uid, &set, &rxBytes, &rxPackets,                   &txBytes, &txPackets) == 9) {            //繞過本地迴環地址            if (strcmp(iface, "lo") && uid == cur_uid && tag == 0L) {                stats->rxBytes += rxBytes;                stats->rxPackets += rxPackets;                stats->txBytes += txBytes;                stats->txPackets += txPackets;            }        }    }    if (fclose(fp) != 0) {        return -1;    }    return 0;}static jlong getUidStat(JNIEnv *env, jclass clazz, jint uid, jint type) {    struct Stats stats;    memset(&stats, 0, sizeof(Stats));    if (parseUidStats(uid, &stats) == 0) {        return getStatsType(&stats, (StatsType) type);    } else {        return UNKNOWN;    }}

這段代碼裡面,需要注意的點是如何忽略本地迴環流量

if (strcmp(iface, "lo") && uid == cur_uid && tag == 0L) {

因為iface是網路類型,一共只有三個類型,rmnet表示2G/3G, wlan表示Wifi流量,lo表示本地流量。所以這裡直接使用了字串比對的方式。

擴充
  • /proc/net/xt_qtaguid/iface_stat_fmt:該檔案中已經按照類型統計出了不同類型網路資料的總數,因此擷取當前裝置的總接受位元組數等裝置級統計資訊,直接分析該檔案,能最快擷取結果
  • /proc/net/xt_qtaguid/stats:該檔案中則是按照uid進行了分類,適合於做更細力度(應用級/線程級)的分析
附錄:
  • 部落格原地址:https://chchaooo.github.io/2018/06/13/Android%E6%B5%81%E9%87%8F%E7%BB%9F%E8%AE%A1/
  • 如果有問題交流請移步:https://www.cnblogs.com/weilf/p/9180373.html
參考資料:
  • Android流量最佳化(一):模組化流量統計
  • Android效能測試之網路流量

Android流量統計

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.