深刻探索 Android 網絡優化(3、網絡優化篇)上

前言

成爲一名優秀的Android開發,須要一份完備的知識體系,在這裏,讓咱們一塊兒成長爲本身所想的那樣~。

本文思惟導圖

1、網絡優化維度

一、網絡優化分析

基礎網絡的效率就像一輛列車,時延是火車的速度 (啓動時間),而帶寬就像火車的車箱裝載量,整個傳輸的物理鏈路就像火車的鐵軌。從網絡的通訊過程來看,共涉及到 三個模塊html

  • 1)、 網絡庫 SDK 內部的設計與策略:I/O 併發模型,針對網絡問題的優化
  • 2)、 服務器性能:併發、帶寬能力
  • 3)、 網絡相關:用戶網絡(弱網/強網)、運營商、網絡鏈路等

而對於網絡的優化,咱們能夠從如下五個維度來進行。java

1)、流量優化

精確獲取網絡流量的消耗量,解決總體均值掩蓋單點異常流量的問題。android

2)、網絡監控

建設全面的網絡監控,由於粗粒度的監控不可以幫助咱們發現和解決問題。git

3)、流量消耗

  • 一、精準獲取一段時間的流量消耗、網絡類型、先後臺。
  • 二、用戶流量消耗均值、異常率(消耗多、次數多)。
  • 三、完整鏈路全監控(Request、Response)、主動上報。

4)、網絡請求質量

  • 一、請求時長、業務成功率、失敗率、TOP 失敗接口,致使請求失敗的緣由一般有兩種狀況:
    • 1)、弱信號:能夠簡單當作手機信號只有一兩格的時候,這是不只僅是信令(無線網絡通訊的都是一個個的信令)發出去困難,還可能致使不斷切換網絡、基站。App 只能在應用層作重試,由於弱信號通常都是一時的。
    • 2)、擁塞網絡:能夠類比爲堵車、排隊的場景,數據包排隊,信令也在排隊。這時 App 不斷重試,只會使得擁塞網絡更爲嚴重。咱們只能讓本身的非核心業務不要去排隊,並讓核心業務的數據量更少,協議來回更少。
  • 二、用戶體驗
  • 三、請求速度、成功率:網絡正常時如何更好地利用帶寬提高網絡請求速度?
  • 四、弱網:網絡不穩定是如何最大程度上保證網絡的連通性?
  • 五、安全:如何防止被第三方劫持、竊聽甚至篡改?

5)、其它

  • 一、公司成本
  • 二、帶寬、服務器數量、CDN
  • 三、耗電

二、網絡優化誤區

  • 1)、僅僅關注流量消耗,忽視其它維度。
  • 2)、僅僅關注均值、總體、忽視個體。

2、網絡優化工具

一、Network Profiler

特色

  • 1)、顯示實時網絡活動:發送、接收數據及鏈接數。
  • 2)、需啓動高級分析。
  • 3)、僅支持 HttpURLConnection 與 OkHttp

打開高級分析

Run => Edit Cofigurations => 界面最右邊 Profiling => 打開 Enable advanced profiling (required for API level < 26 only)github

使用 Network Profiler 調試 WanAndroid 網絡請求

選中目標網絡請求,能夠看到在下方的 Connection View 一欄看到對應的網絡數據,以下所示:web

  • Size
  • Type
  • Status
  • Time
  • Timeline

選中 Connection View 特定的一條數據便可在右邊看到該請求對應的網絡數據。chrome

Overview

該網絡請求的預覽信息json

普通 Json 數據請求

圖片加載請求

Response

Response Header 與 Body 信息數組

Request

Request Header 與 Body 信息瀏覽器

CallStack

網絡請求的調用堆棧信息, 下圖就是 Awesome-WanAndroid 發起一個網絡請求所經歷的調用堆棧:

Awesome-WanAndroid 使用 Glide 發起一個圖片加載請求所經歷的調用堆棧:

關鍵細節

高級配置中的 required for API level < 26 only 不是限定調試的手機版本小於26,我使用 API 27 的手機也能夠調試。

實踐中得到的新知識及感悟

若是想快速搞懂接手項目中的網絡/圖片加載等框架的w網絡請求流程,可使用 Profiler NETWORK 的 CallStack 功能,而且雙擊其中任意的一行調用鏈方法均可以 jump to 指定源碼。

選中網絡請求沒法顯示數據?

打開高級分析便可。

二、Charles

使用 Java 開發的,MAC 上使用較多。

特色

  • 1)、斷點功能
  • 2)、Map Local
  • 3)、弱網環境模擬

安裝配置

一、下載 Charles

二、截獲手機端的網絡包。

須要配置手機與電腦鏈接同一 WIFI。

1)、電腦端設置 Charles — 打開 HTTP 代理並設置代理端口
  • Charles 菜單欄 => Proxy => Proxy Settings => 填代理端口 8888 並勾選 Enable transparent HTTP proxying。
2)、手機端設置 WIFI 代理及端口
  • 獲取電腦 IP 地址
    • 點擊 Charles 的 help => local address。
  • 設置 WIFI 代理及端口號
    • 手機設置 => WLAN => 查看當前鏈接的 WIFI 詳情 => 最底部代理項設置爲手動 => 配置 電腦 IP 地址與端口號8888。
3)、設置完成,運行任意聯網程序,Charles 會彈出請求鏈接的確認框,點擊 allow 便可。

三、截取 HTTPS

須要信任 Charles 的 CA 證書。

1)、打開 SSL 代理,並配置 Host 與 Port
  • 電腦端 Proxy => SSL Proxying Setting => 選中 Enable SSL Proxying 並點擊 Add 配置 Host 與 Port 分半爲 * 與 443。
2)、信任 Charles Proxy CA 機構
  • 電腦端 Help => SSL Proxying => Install Charles Root Certificate => 選中並雙擊 Charles Proxy CA 根證書頒發機構 => 點擊信任 => 使用此證書時選擇始終信任。
3)、手機端安裝 Charles 頒發的 SSL 證書
  • 電腦端 Help => SSL Proxying => Install Charles Root Certificate on a Mobile Device,此時會彈出提示框讓手機端訪問 http://chls.pro/ssl 去下載證書。
4)、手機端安裝證書
  • 從文件管理器中找到下載文件 => 若是是 .pem 結尾i,將後綴名改成 .crt 並點擊該文件 => 輸入鎖屏密碼 => 等待證書導入後配置證書名(我填的是 Charles)便可。

實踐過程

選中目標網絡請求

從 Overview 中能夠看到很全面抓包信息 。

使用斷點功能

1)、右鍵點擊要斷點的 URL,選中 BreakPoints 開啓斷點功能。
2)、點擊頂部 Proxy => Breadkpoint Settings。
3)、雙擊 Breakpoints Settings 面板中的目標

URL,在彈出的 Edit Breakpoint 面板中進行編輯。

4)、這裏默認選擇斷點 Request 與 Response,咱們能夠選擇僅斷點 Response 或 Request。點擊確認即斷點設置完成。
5)、而後,咱們就能夠點擊主面板右側的 Edit Response 編輯 Response,修改完成後點擊最下方的 Execute 便可。

使用 Map Local

1)、自由模擬服務端的返回數據,以提早進行接口測試。
1)、右鍵點擊要使用 Map Local 的 URL,選中Map Local 開啓斷點功能。
1)、而後,咱們在 Edit Mapping 面板中選擇 Map To 的 Local path,選擇本地設定的 maplocal 本地數據(例如 JsonString)

弱網模擬功能

  • 1)、注意開啓前需將 Map Local 關閉。

  • 2)、點擊 Proxy => Throttle Setting => 選中 Enable Throttling

  • 3)、這裏預設了不少模擬設置,咱們只需將 網絡包傳輸的速率 Throttle preset 設置爲較低的速率(通常設爲 256/512)。

碰到的問題

  • 1)、注意手機與筆記本電腦須要同一 WIFI 下,不能本身開熱點或使用公司內網,不然沒法在 電腦端 沒法彈出手機鏈接 Charles 的提示確認框,而且也沒法下載 Charles 提供的 SSL 證書。
  • 2)、手機端下載 Charles 提供的 SSL 證書時最好不使用系統瀏覽器訪問。

三、Wireshark

強烈推薦 geektime-webprotocol

WireShark 主要能夠用來對四種流進行跟蹤,以下所示:

  • TCP
  • UDP
  • SSL
  • HTTP

1)、WireShark 基本使用

如何捕獲報文

  • 1)、點擊捕獲->選項,打開捕獲窗口
    • 網卡設備/流量/捕獲過濾器,點擊「開始」按鈕開始抓包
    • 輸出(指定緩存文件)/選項(顯示、名稱解析、自動中止抓包條件) 面板
  • 2)、點擊捕獲->中止,中止抓包

Wireshark 面板

快捷方式工具欄

數據包的顏色(視圖->着色規則)

設定時間顯示格式

數據包列表面板的標記符號

文件操做

  • 1)、標記報文 Ctrl+M。
  • 2)、導出標記報文(文件->導出特定分組),亦可按過濾器導出報文 ,
  • 3)、合併讀入多個報文(文件->合併)。

如何快速抓取移動設備的報文?

  • 一、打開手機的 wifi 熱點。
  • 二、電腦鏈接手機的 wifi 熱點。
  • 三、用 Wireshark 打開捕獲->選項面板,選擇 wifi 熱點對應的接口設備抓包便可。

2)、Wireshark 過濾器

若是表達式的背景爲綠色,則說明過濾器的語法是正確的,紅色則說明有錯誤。

捕獲過濾器

它用於減小抓取的報文體積,使用 BPF(Berkeley Packet Filter) 語法,功能相對有限。

BPF 能夠在設備驅動級別提供抓包過濾接口,多數抓包工具都支持此語法。而 BPF 的 Expression 表達式由多個 primitives 原語組成。而每個 primitives 原語則由名稱或數字,以及描述它的多個 qualifiers 限定詞組成。

qualifiers 限定詞
  • 一、Type:設置數字或者名稱所指示類型
    • host、port。
    • net ,設定子網,net 192.168.0.0 mask 255.255.255.0 等價於 net 192.168.0.0/24。
    • portrange,設置端口範圍,例如 portrange 6000-8000。
  • 二、Dir:設置網絡出入方向
    • src、dst、src or dst、src and dst。
    • ra、ta、addr一、addr二、addr三、addr4(僅對 IEEE 802.11 Wireless LAN 有效)。
  • 三、Proto:指定協議類型
    • ether、fddi、tr、 wlan、
    • ip、 ip六、 arp、 rarp、
    • decnet、 tcp、udp、icmp、igmp、icmp
    • igrp、pim、ah、esp、vrrp
  • 四、其餘
    • gateway:指明網關 IP 地址,等價於 ether host ehost and not host host。
    • broadcast:廣播報文,例如 ether broadcast 或者 ip broadcast。
    • multicast:多播報文,例如 ip multicast 或者 ip6 multicast。
    • less, greater:小於或者大於。

簡單示例

src or dst portrange 6000-8000 && tcp or ip6
複製代碼

顯示過濾器

它對已經抓取到的報文進行過濾顯示,功能強大。

基於協議域過濾
  • 捕獲全部 TCP 中的 RST 報文:tcp[13]&4==4。
  • 抓取 HTTP GET 報文:port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420。(47455420 是 ASCII 碼的 16 進制,表示」GET 」)
  • 抓取 HTTP POST 報文:port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354
顯示過濾器的過濾屬性

任何在報文細節面板中解析出的字段名,均可以做爲過濾屬性。在視圖->內部->支持的協議面板裏,能夠看到各字段名對應的屬性名。例如,在報文細節面板中 TCP 協議頭中的 Source Port,對應着過濾屬性爲 tcp.srcport。

經常使用操做符
  • 1)、and(&&):AND 邏輯與,ip.src==10.0.0.5 and tcp.flags.fin。
  • 2)、or(||):OR 邏輯或,ip.scr==10.0.0.5 or ip.src==192.1.1.1。
  • 3)、xor(^^):XOR 邏輯異或,tr.dst[0:3] == 0.6.29 xor tr.src[0:3] == 0.6.29。
  • 4)、not(!):NOT 邏輯非,not llc。
  • 5)、[...​]:中括號[]Slice 切片操做符
    • [n:m]表示 n 是起始偏移量,m 是切片長度,例如:eth.src[0:3] == 00:00:83
    • [n-m]表示 n 是起始偏移量,m 是截止偏移量,例如:eth.src[1-2] == 00:83
    • [:m]表示從開始處至 m 截止偏移量,例如:eth.src[:4] == 00:00:83:00
    • [m:]表示 m 是起始偏移量,至字段結尾,例如:eth.src[4:] == 20:20
    • [m]表示取偏移量 m 處的字節,例如:eth.src[2] == 83
    • [,]使用逗號分隔時,容許以上方式同時出現,例如:eth.src[0:3,1-2,:4,4:,2] ==00:00:83:00:83:00:00:83:00:20:20:83
  • 6)、in:大括號{}集合操做符,例如 tcp.port in {443 4430..4434} ,實際等價於 tcp.port == 443 || (tcp.port >= 4430 && tcp.port ⇐ 4434)。
可用函數
  • upper:將字符串字段轉換爲大寫。
  • lower:將字符串字段轉換爲小寫。
  • len:返回字符串或字節數組的字節長度。
  • count:返回在一幀中字段出現的數量。
  • string:將非字符串字段轉換爲字符串。
顯示過濾器的可視化對話框
環形緩衝器

例如使用 3 個文件的環形緩存器,從 **.1 => **.2 => **.3 而後又從 **.1 文件開始記錄,造成環形。

四、TcpDump(網絡數據包嗅探器)

1)、抓包步驟

一、獲取 ROOT 權限的手機一部

二、下載 tcpdump

三、將 tcpdump 安裝到手機上

adb push tcpdump /data/local/tmp
複製代碼

四、修改 tcpdump 的權限,使其具備可執行的權限

chmod 777 /data/local/tmp/tcpdump
複製代碼

五、執行 tcpdump 命令進行抓包,按組合鍵 Ctrl + C 能夠中止抓包

六、將抓到的數據包的信息保存爲 Pcap 文件,這裏僅需在執行 tcpdump 後加上 -w 參數

tcpdump-w /data/local/tmp/tcp.pcap
複製代碼

七、把 Pcap 複製到 電腦上,使用 Wireshark 分析數據包的流量。

2)、捕獲及中止條件

  • -D:列舉全部網卡設備。
  • -i:選擇網卡設備。
  • -c:抓取多少條報文。
  • --time-stamp-precision:指定捕獲時的時間精度,默認毫秒 micro,可選納秒 nano。
  • -s:指定每條報文的最大字節數,默認 262144 字節。

3)、文件操做

  • -w:輸出結果至文件(可被Wireshark讀取分析)。
  • -C:限制輸入文件的大小,超出後之後綴加 1 等數字的形式遞增。 注意單位是 1,000,000 字節。
  • -W:指定輸出文件的最大數量,到達後會從新覆寫第 1 個文件。
  • -G:指定每隔N秒就從新輸出至新文件,注意-w 參數應基於 strftime 參數指定文件名。
  • -r:讀取一個抓包文件。
  • -V:將待讀取的多個文件名寫入一個文件中,經過讀取該文件同時 讀取多個文件。

4)、輸出時間戳格式

  • -t:不顯示時間戳。
  • -tt:自1970年1月1日0點至今的秒數。
  • -ttt:顯示鄰近兩行報文間通過的秒數。
  • -tttt:帶日期的完整時間。
  • -ttttt:自第一個抓取的報文起經歷的秒數。

5)、分析信息詳情

  • -e:顯示數據鏈路層頭部。
  • -q:不顯示傳輸層信息。
  • -v:顯示網絡層頭部更多的信息,如 TTL、id 等。
  • -n:顯示 IP 地址、數字端口代替 hostname 等。
  • -S:TCP 信息以絕對序列號替代相對序列號。
  • -A:以 ASCII 方式顯示報文內容,適用 HTTP 分析。
  • -x:以 16 進制方式顯示報文內容,不顯示數據鏈路層。
  • -xx:以 16 進制方式顯示報文內容,顯示數據鏈路層。
  • -X:同時以 16 進制及 ACII 方式顯示報文內容,不顯示數據鏈路層 • -XX 同時以 16 進制及 ACII 方式顯示報文內容,顯示數據鏈路層。

五、Stetho

  • 1)、在 build.gradle 中,除了 Stetho 依賴外,還需添加 'com.facebook.stetho:stetho-okhttp3:1.5.0'。
  • 2)、在 Application 的 onCreate 方法中初始化 'Stetho.initializeWithDefaults(this)'。
  • 3)、調用 OkHttp 的 'addNeworkInterceptor' 方法添加 Stetho 用於收集網絡信息而提供的網絡攔截器。
  • 4)、訪問 Chrome 調試頁面 'chrome://inspect'。

六、其它的性能檢測工具

  • strace:跟蹤 Socket 相關的系統調用。
  • netstat:記錄多種網絡棧和接口統計信息。
  • ifconfig:記錄接口配置。
  • ip:記錄網絡接口統計信息。
  • ping:測試網絡連通性。
  • traceroute:測試網絡路由。
  • /proc/net 命令:查看網絡統計信息,Android TrafficState 使用了 /proc/net/xt_qtaguid/stats 和 /proc/net/xt_qtaguid/iface_stat_fmt 文件來統計 App 的流量信息。

3、精準獲取流量消耗

一、如何判斷 App 流量消耗偏高?

  • 1)、絕對值看不出高低。
  • 2)、對比競品,相同 Case 對比流浪消耗。
  • 3)、異常監控超過正常指標。

二、測試方案

  • 1)、打開手機設置 => 流量管理 => 僅容許目標 App 聯網
  • 2)、能夠查找出大多數的問題,可是線上場景線下可能遇不到。

三、線上流量獲取方案

1)、TrafficStats

特色

  • API 18 以上。
  • 記錄手機重啓以來的數據流量。

API

  • getMobileRxBytes():經過蜂窩流量接收到的信息。
  • getUidRxBytes(int uid):獲取指定 uid 的接收流量。
  • getTotalRxBytes():總髮送流量。

缺點

沒法獲取某個時間段內的流量消耗。

2)、NetworkStatsManager

API 23 以後。

特色

  • 1)、獲取指定時間間隔內的流量信息。
  • 2)、獲取不一樣網絡類型下的消耗。

NetUtils.getStats

獲取指定時間間隔的 蜂窩 + WIFI 流量總信息

四、先後臺流量獲取方案

問題:線上反饋 App 後臺流量消耗大?

只獲取一個時間段的流量不夠全面。

實現原理

後臺定時任務 => 獲取時間間隔內流量 => 記錄先後臺 => 分別計算 => 上報 APM 後臺 => 流量治理依據

小結

  • 1)、該方案沒法獲取應用在先後臺切換時的流量,所以有必定的偏差,但這個偏差是能夠接受的。
  • 2)、結合精細化的流量異常報警針對性的解決後臺跑流量的問題。

成功 log 以下所示:

2020-05-11 10:47:55.633 4036-4181/json.chao.com.wanandroid I/WanAndroid-LOG: │ [MainActivity.java | 193 | lambda$initEventAndData$1$MainActivity] backNetUseData: 4 MB
2020-05-11 10:47:55.646 4036-4181/json.chao.com.wanandroid I/WanAndroid-LOG: │ [MainActivity.java | 194 | lambda$initEventAndData$1$MainActivity] foreNetUseData: 4 MB 2020-05-11 10:47:55.652 4036-4181/json.chao.com.wanandroid I/WanAndroid-LOG: │ [MainActivity.java | 197 | lambda$initEventAndData$1$MainActivity] totalNetUseData: 8 MB 複製代碼

4、網絡請求流量優化

一、常見使用網絡的場景

1)、數據壓縮

POST 請求 Body 使用 GZip 壓縮,同時服務端返回 Body 也使用 GZip 壓縮。

2)、圖片

  • 圖片上傳前壓縮。
  • 圖片使用策略細化:讓 服務端/CDN 雲服務器 優先使用縮略圖/WebP格式圖片。

3)、性能日誌上報:批量 + 特定場景上報

APM 相關、單點問題相關。例如埋點數據能夠等到某一時機點(例如 開啓了 WIFI、數據量過大必須上傳一部分時)再上傳。

4)、數據緩存

服務端返回加上過時時間,避免每次從新獲取。 節約流量且大幅提升數據訪問速度,更好的用戶體驗。

Request 緩存設置

  • 一、Pragma:no-cache:去服務器拉取最新的資源,不使用緩存。
  • 二、If-Modified-Since:datetime:若是資源在客戶端提供的時間後發生改變,服務器會返回新的資源,不然使用緩存。
  • 三、If-None-Match:etagvalue:若是資源的標識和服務器的不一樣,返回新的資源。

當 Request 的頭部是 2 和 3 時,若是服務器的資源沒有修改,則服務器會返回 HTTP/304 Not Modified,客戶端會使用緩存的 Response。

Response 緩存設置

HTTP Response 是否能夠緩存是由 Response 的頭部控制的,服務器能夠經過 Expires 和 Cache-Control 控制 Response 如何在客戶端緩存。

Expires

Expires 頭部會包含一個日期,即該資源緩存的有效期,客戶端有新的相同請求時,若是資源緩存沒有過時,則使用緩存資源,服務器不會返回任何東西。

Cache-Control

Cache-Control 能夠標明 Response 如何存儲及其如何使用,其選項以下所示:

  • 1)、public:Response 能夠存儲在任何 Cache 中,包括共享的 Cache。
  • 2)、private:Response 存儲在私有 Cache 中,只能被一個用戶使用。
  • 3)、no-cache:Response 未來不會被使用。
  • 4)、no-store:Response 未來不會被使用,也不會寫到磁盤上。
  • 5)、max-age=#seconds:Response 在設定的時間內能夠被重複使用。
  • 6)、must-revalidate:和原始服務器確認 Response 是最新後,可使用緩存。

OKHttp 無網數據緩存實現

POST 在 OKHttp 中默認不會緩存,由於 POST 通常是用來修改數據的。在 Awesome-WanAndroid 中的 HttpModule—cacheInterceptor 中就已經實現了 OKHttp 的無網數據緩存,代碼以下所示:

File cacheFile = new File(Constants.PATH_CACHE);
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50); Interceptor cacheInterceptor = chain -> {  Request request = chain.request();  if (!CommonUtils.isNetworkConnected()) {  // 無網時強制使用數據緩存,以提高用戶體驗。  request = request.newBuilder()  .cacheControl(CacheControl.FORCE_CACHE)  .build();  }  Response response = chain.proceed(request);  if (CommonUtils.isNetworkConnected()) {  int maxAge = 0;  // 有網絡時, 不緩存, 最大保存時長爲0  response.newBuilder()  .header("Cache-Control", "public, max-age=" + maxAge)  .removeHeader("Pragma")  .build();  } else {  // 無網絡時,設置超時爲4周  int maxStale = 60 * 60 * 24 * 28;  response.newBuilder()  .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)  .removeHeader("Pragma")  .build();  }  return response; }; // 緩存優化 builder.addNetworkInterceptor(cacheInterceptor); builder.addInterceptor(cacheInterceptor); builder.cache(cache); 複製代碼

5)、離線包、增量數據更新

加上版本的概念,僅傳輸有變化的數據。

6)、請求頭壓縮

若是請求頭不變,服務端可使用映射緩存 請求頭 MD5 : 請求頭,以後請求頭都使用 MD5 便可。

7)、優化發送頻率和時機

8)、合併網絡請求、減小請求次數。

9)、流量兜底能力

若是發現流量異常,咱們能夠經過後臺服務器終止協議交互,以免問題惡化。

二、流量統計

咱們能夠利用 network-connection-class 進行流量統計,它內部使用的是 API 8 的 TrafficStats 類,用於獲取整個手機或者某個 UID 從開機算起的網絡流量。

1)、四個核心 API

// 從開機開始Mobile網絡接收的字節總數,不包括Wifi
getMobileRxBytes() // 從開機開始全部網絡接收的字節總數,包括Wifi getTotalRxBytes() // 從開機開始Mobile網絡發送的字節總數,不包括Wifi getMobileTxBytes() // 從開機開始全部網絡發送的字節總數,包括Wifi getTotalTxBytes() 複製代碼

2)、對應的Linux 內核 proc 統計接口

// stats接口提供各個uid在各個網絡接口(wlan0, ppp0等)的流量信息
/proc/net/xt_qtaguid/stats // iface_stat_fmt接口提供各個接口的彙總流量信息 proc/net/xt_qtaguid/iface_stat_fmt 複製代碼

3)、工做原理

  • 1)、讀取 proc,並將目標 UID 下面全部網絡接口的流量相加。
  • 2)、Android 7.0 以後只能經過 TrafficStats 拿到本身應用的流量信息。

《深刻探索 Android 性能優化(3、網絡優化篇)下》將在本週四發佈,敬請期待。

公衆號

個人公衆號 JsonChao 開通啦,若是想第一時間(明天8:30)查看《深刻探索 Android 性能優化(3、網絡優化篇)下》,歡迎掃描二維碼進行閱讀~

參考連接:


Contanct Me

● 微信:

歡迎關注個人微信:bcce5360

● 微信羣:

因爲微信羣人數過多,麻煩你們想進微信羣的朋友們,加我微信拉你進羣。

● QQ羣:

2千人QQ羣,Awesome-Android學習交流羣,QQ羣號:959936182, 歡迎你們加入~

About me

很感謝您閱讀這篇文章,但願您能將它分享給您的朋友或技術羣,這對我意義重大。

但願咱們能成爲朋友,在 Github掘金上一塊兒分享知識。

相關文章
相關標籤/搜索