Сетевой трафик, генерируемый приложением, может значительно влиять на время работы устройства от батареи. Чтобы оптимизировать этот трафик, вам нужно измерить его и определить его источник. Сетевые запросы могут поступать непосредственно от действий пользователя, из кода вашего приложения или от сервера, взаимодействующего с вашим приложением.
В этом документе рассказывается, как отслеживать и классифицировать сетевой трафик, а также как выявлять и устранять проблемы.
Как отслеживать запросы с помощью Профилировщика сети
Используйте Профилировщик сети, чтобы отслеживать сетевые запросы приложения. Вы можете отслеживать, как и когда ваше приложение передает данные, и оптимизировать его код.
Отслеживая частоту передачи данных и объем передаваемых данных во время каждого подключения, вы можете определить области вашего приложения, которые можно сделать более энергоэффективными. Как правило, вы будете искать короткие пики, которые могут задерживаться.
Чтобы вам было проще выявлять причины скачков трафика, Traffic Stats API позволяет помечать передачу данных из сокета в определенном потоке с помощью TrafficStats.setThreadStatsTag().
Вызов этой функции не приводит к автоматической пометке всего трафика для определенного потока. Теги должны быть применены к сокетам.
После того как тег потока задан, вы можете вручную помечать и снимать пометки с отдельных сокетов, используя TrafficStats.tagSocket() и TrafficStats.untagSocket().
Тег также применяется, если в потоке открывается сокет или если серверный сокет принимает подключение.
При одновременном доступе к одному сокету из нескольких потоков будет использоваться тег, который был у сокета при отправке или получении сетевых пакетов. Из-за буферизации и повторной передачи он может отличаться от тега, который был у сокета, когда пользователь записывал или считывал данные.
Например, вы можете определить константы, представляющие разные типы сетевого трафика, как показано в следующем примере кода:
const val USER_INITIATED = 0x1000 const val APP_INITIATED = 0x2000 const val SERVER_INITIATED = 0x3000
Затем вы можете добавить в сетевые запросы соответствующие теги:
TrafficStats.setThreadStatsTag(USER_INITIATED) try { TrafficStats.tagSocket(outputSocket) try { // Transfer data using socket. } finally { TrafficStats.untagSocket(outputSocket) } } finally { TrafficStats.clearThreadStatsTag() }
Библиотека HttpURLConnection автоматически помечает сокеты на основе текущего значения TrafficStats.getThreadStatsTag(). Библиотека также помечает и снимает пометки с сокетов, когда они повторно используются через пулы keep-alive, как показано в следующем примере кода:
class IdentifyTransferSpikeTask { @WorkerThread fun request(url: String) { TrafficStats.setThreadStatsTag(APP_INITIATED) try { // Make network request using HttpURLConnection.connect(). val connection = URL(url).openConnection() as HttpURLConnection try { connection.connect() // ... } finally { connection.disconnect() } } finally { TrafficStats.clearThreadStatsTag() } } }
Анализ типов сетевого трафика
Чтобы оптимизировать сетевой трафик, генерируемый вашим приложением, нужно понимать, откуда он поступает. Частая сетевая активность, генерируемая вашим приложением, может быть вполне уместной, если она является ответом на действия пользователя, но совершенно неуместной, если ваше приложение не находится на переднем плане или если устройство находится в кармане или сумочке.
Анализ трафика, инициированного пользователями
Сетевой трафик, инициированный пользователем, может быть эффективно сгруппирован, пока пользователь выполняет определенную задачу в вашем приложении, или распределен неравномерно, когда пользователь запрашивает дополнительную информацию, которую ваше приложение должно получить. Ваша цель при анализе сетевого трафика, инициированного пользователем, – найти закономерности частого использования сети с течением времени и попытаться снизить их частоту, сгруппировав запросы вместе.
Непредсказуемость запросов пользователей затрудняет оптимизацию этого типа использования сети в вашем приложении. Кроме того, пользователи ожидают быстрых ответов, когда они активно используют приложение, поэтому задержка запросов в целях повышения эффективности может привести к ухудшению пользовательского опыта. В целом, когда пользователь напрямую взаимодействует с вашим приложением, вы должны отдавать приоритет быстрому ответу пользователю, а не эффективному использованию сети.
Рекомендации по оптимизации трафика, инициированного пользователями, приведены в этой статье.
Анализ трафика, инициированного приложением
Сетевой трафик, инициированный приложением, – это область, в которой вы можете значительно повлиять на эффективность использования пропускной способности сети. Анализируя сетевую активность приложения, ищите периоды бездействия и определяйте, можно ли их увеличить. Если вы видите, что приложение постоянно обращается к сети, попробуйте объединить этот трафик в пакеты, чтобы радиомодуль устройства мог переключаться в режим низкого энергопотребления между периодами активности.
Ознакомьтесь с рекомендациями по оптимизации трафика, инициированного приложением, в статье Как оптимизировать запросы, инициированные приложением.
Анализ трафика, инициированного сервером
Сетевая активность, инициированная серверами, которые взаимодействуют с вашим приложением, – это ещё одна область, где вы можете значительно повлиять на эффективность использования пропускной способности сети. Firebase Cloud Messaging (FCM) – это простой механизм, который используется для передачи данных с сервера в определенный экземпляр приложения. С помощью FCM ваш сервер может уведомлять приложение, запущенное на определенном устройстве, о том, что для него доступны новые данные.
Рекомендации по оптимизации трафика, инициированного сервером, приведены в статье Как оптимизировать запросы, инициированные сервером.
Используйте Battery Historian для визуализации эффектов сетевого трафика
Battery Historian – это инструмент, который позволяет визуализировать расход заряда батареи устройства за определенный период времени. С помощью этого инструмента можно проанализировать, как сетевая активность влияет на расход заряда батареи. Например, Battery Historian может показать, использует ли ваше приложение приемопередатчик чаще, чем вы ожидаете. Дополнительную информацию об использовании Battery Historian можно найти в статье Как анализировать расход заряда батареи с помощью Batterystats и Battery Historian.