排查网络问题

应用产生的网络流量会对设备的电池续航时间产生重大影响。为了优化这些流量,您需要对其进行衡量并确定其来源。网络请求可能直接来自用户操作,来自您自己的应用代码的请求,或者来自与您的应用通信的服务器。

本主题介绍了如何监控和分类网络流量,并提供有关如何识别和解决问题的指南。

使用网络性能分析器监控请求

使用 Network Profiler 跟踪应用的网络请求。您可以监控应用传输数据的方式和时间,并适当优化底层代码。



图 1. 跟踪网络流量。网络流量模式表明,通过预先抓取请求或整合上传可以显著提高效率。

通过监控数据传输频率和每次连接期间传输的数据量,您可以确定应用的哪些方面可以实现更高的电池效率。通常,您会寻找可能延迟的短暂峰值。

为了更好地识别形成传输峰值的原因,借助 Traffic Stats API,您可以使用 TrafficStats.setThreadStatsTag() 对在给定线程中通过套接字发生的数据传输进行标记。调用此函数不会自动为特定线程的所有流量添加标记;必须将标记应用于套接字。

设置线程标记后,您可以使用 TrafficStats.tagSocket()TrafficStats.untagSocket() 手动标记和取消标记各个套接字。如果套接字在线程上打开,或者服务器套接字接受了连接,也会应用标记。

多个线程对同一套接字的并发访问将使用套接字在发送或接收网络数据包时所具有的任何标记(由于缓冲和重传,该标记可能与用户写入或读取数据时所具有的标记不同)。

例如,您可以定义常量来表示不同类型的网络流量,如以下代码示例所示:

Kotlin

const val USER_INITIATED = 0x1000
const val APP_INITIATED = 0x2000
const val SERVER_INITIATED = 0x3000

Java

public static final int USER_INITIATED = 0x1000;
public static final int APP_INITIATED = 0x2000;
public static final int SERVER_INITIATED = 0x3000;

然后,您可以相应地标记您的网络请求:

Kotlin

TrafficStats.setThreadStatsTag(USER_INITIATED)
TrafficStats.tagSocket(outputSocket)
// Transfer data using socket
TrafficStats.untagSocket(outputSocket)

Java

TrafficStats.setThreadStatsTag(USER_INITIATED);
TrafficStats.tagSocket(outputSocket);
// Transfer data using socket
TrafficStats.untagSocket(outputSocket);

HttpURLConnection 库会根据当前的 TrafficStats.getThreadStatsTag() 值自动对套接字进行标记。在通过 keep-alive 池进行再循环时,此库还会对套接字进行标记和取消标记,如下面的代码示例所示:

Kotlin

class IdentifyTransferSpikeTask {
    @WorkerThread
    fun request(url: String) {
        TrafficStats.setThreadStatsTag(APP_INITIATED)
        // Make network request using HttpURLConnection.connect()
        ...
        TrafficStats.clearThreadStatsTag()
    }
}

Java

public class IdentifyTransferSpikeTask {
    @WorkerThread
    public void request(String url) {
        TrafficStats.setThreadStatsTag(APP_INITIATED);
        // Make network request using HttpURLConnection.connect()
        ...
        TrafficStats.clearThreadStatsTag();
    }
}

分析网络流量类型

在查看应用产生的网络流量时,您需要了解流量来源,以便对其进行适当优化。 当应用响应用户操作时,应用产生频繁的网络活动可能完全合适,但如果应用不在前台,或者设备放在口袋或钱包中不用,则完全不合适。

分析用户发起的流量

当用户在您的应用中执行特定任务时,用户发起的网络流量可能会高效地组合在一起,而当用户请求应用需要获取的额外信息时,用户发起的网络流量则会分布不均。分析用户发起的网络流量的目标是查找在一段时间内频繁使用网络的模式,并尝试通过将请求分组来降低其频率。

由于用户请求具有不可预测性,因此很难在应用中优化这种类型的网络使用。此外,当用户正在活跃地使用应用时,他们会希望应用能够快速响应,因此为了提高效率而延迟请求可能会导致用户体验不佳。一般来说,当用户正在直接与您的应用进行互动时,您应该优先考虑对用户的快速响应,而非提高网络使用效率。

如需有关优化用户发起的流量的建议,请参阅优化用户发起的请求

分析应用发起的流量

应用发起的网络流量通常会对网络带宽的使用效率产生重大影响。在分析应用的网络活动时,请查找无活动时段并确定是否可以增加这些时段。如果您发现应用对网络的访问呈现出一致的模式,请尝试批量处理此类流量,以便设备无线装置可以在活动期间切换回低功耗模式。

如需获取优化应用发起的流量的建议,请参阅优化应用发起的请求

分析服务器发起的流量

与应用通信的服务器发起的网络活动通常也会对网络带宽的使用效率造成重要影响。Firebase Cloud Messaging (FCM) 是一种轻量级机制,用于将数据从服务器传输到特定应用实例。借助 FCM,您的服务器可以通知您在特定设备上运行的应用有新数据可用。

如需有关优化服务器发起的流量的建议,请参阅优化服务器发起的请求

使用 Battery Historian 直观呈现网络流量影响

Battery Historian 是一款可直观呈现设备在一段时间内的耗电情况的工具。您可以使用此工具分析网络活动对电池消耗的影响。例如,Battery Historian 可以显示应用使用移动网络无线装置的频率是否高于您的预期。如需详细了解如何使用 Battery Historian,请参阅使用 Batterystats 和 Battery Historian 分析电池用量