安卓面试网络

Android 网络优化(下)

2020-10-22  本文已影响0人  凯玲之恋

一、网络优化维度

1、网络优化分析

基础网络的效率就像一辆列车,时延是火车的速度 (启动时间),而带宽就像火车的车厢装载量,整个传输的物理链路就像火车的铁轨。从网络的通信过程来看,共涉及到 三个模块

而对于网络的优化,我们可以从以下五个维度来进行。
1)、流量优化
精确获取网络流量的消耗量,解决整体均值掩盖单点异常流量的问题。
2)、网络监控
建设全面的网络监控,因为粗粒度的监控不能够帮助我们发现和解决问题。
3)、流量消耗

2、网络优化误区

二、网络优化工具

1、Network Profiler

特点

使用 Network Profiler 调试 WanAndroid 网络请求
Connection View
选中目标网络请求,可以看到在下方的 Connection View 一栏看到对应的网络数据,如下所示:

Size
Type
Status
Time
Timeline

选中 Connection View 特定的一条数据即可在右边看到该请求对应的网络数据。

Overview
该网络请求的预览信息

普通 Json 数据请求.png 图片加载请求.png
Response
Response Header 与 Body 信息
Request
Request Header 与 Body 信息
CallStack
网络请求的调用堆栈信息, 下图就是 Awesome-WanAndroid 发起一个网络请求所经历的调用堆栈:

2、Charles

特点

Charles

使用断点功能
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)

弱网模拟功能

3、Wireshark

geektime-webprotocol

WireShark 主要可以用来对四种流进行跟踪,如下所示:

TCP
UDP
SSL
HTTP

4、TcpDump(网络数据包嗅探器)

tcpdump

5、Stetho

6、其它的性能检测工具

三、精准获取流量消耗

1、如何判断 App 流量消耗偏高?

2、测试方案

3、线上流量获取方案

1)、TrafficStats

特点

2)、NetworkStatsManager

API 23 之后。
特点

4、前后台流量获取方案

问题:线上反馈 App 后天流量消耗大?
只获取一个时间段的流量不够全面。
实现原理
后台定时任务 => 获取时间间隔内流量 => 记录前后台 => 分别计算 => 上报 APM 后台 => 流量治理依据
小结

四、网络请求流量优化

1、常见使用网络的场景

1)、数据压缩
POST 请求 Body 使用 GZip 压缩,同时服务端返回 Body 也使用 GZip 压缩。
2)、图片

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)、流量兜底能力
如果发现流量异常,我们可以通过后台服务器终止协议交互,以避免问题恶化。

2、流量统计

我们可以利用 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)、工作原理

参考

深入探索 Android 网络优化(三、网络优化篇)上

上一篇 下一篇

猜你喜欢

热点阅读