Сетевой трафик, генерируемый приложением, может существенно влиять на время автономной работы устройства. Для оптимизации этого трафика необходимо измерить его и определить источник. Сетевые запросы могут поступать непосредственно от действий пользователя, из кода вашего приложения или от сервера, взаимодействующего с вашим приложением.
В этой теме показано, как отслеживать и классифицировать сетевой трафик, а также даны рекомендации по выявлению и устранению проблем.
Используйте сетевой профилировщик для мониторинга запросов.
Используйте сетевой профилировщик для отслеживания сетевых запросов вашего приложения. Вы можете контролировать, как и когда ваше приложение передает данные, и соответствующим образом оптимизировать базовый код.

Рисунок 1. Отслеживание сетевого трафика. Структура сетевого трафика указывает на то, что эффективность можно значительно повысить за счет предварительной выборки запросов или объединения загружаемых файлов в пакеты.
Отслеживая частоту передачи данных и объем передаваемых данных за каждое соединение, вы можете выявить области вашего приложения, которые можно оптимизировать с точки зрения энергопотребления. Как правило, вам следует искать кратковременные всплески, которые можно отложить.
Для более точного определения причин всплесков трафика API статистики трафика позволяет помечать передачу данных, происходящую из сокета в рамках заданного потока, с помощью TrafficStats.setThreadStatsTag() . Вызов этой функции не приводит к автоматическому пометке всего трафика для конкретного потока; метки должны быть применены к сокетам.
После установки тега потока вы можете вручную помечать и снимать теги с отдельных сокетов, используя TrafficStats.tagSocket() и TrafficStats.untagSocket() . Тег также применяется, если сокет открывается в потоке или если серверный сокет принимает соединение.
При одновременном доступе к одному и тому же сокету несколькими потоками будет использоваться тот тег, который сокет имел на момент отправки или получения сетевых пакетов (который может отличаться от того, который был у сокета на момент записи или чтения данных пользователем из-за буферизации и повторной передачи).
Например, вы можете определить константы для представления различных типов сетевого трафика, как показано в следующем примере кода:
Котлин
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;
Затем вы можете соответствующим образом пометить свои сетевые запросы:
Котлин
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, как показано в следующем примере кода:
Котлин
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» .