Устранение проблем с сетью

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

В этом разделе показано, как отслеживать и классифицировать сетевой трафик, а также даются рекомендации по выявлению и решению проблем.

Используйте Network Profiler для мониторинга запросов

Используйте Network Profiler для отслеживания сетевых запросов вашего приложения. Вы можете отслеживать, как и когда ваше приложение передает данные, и соответствующим образом оптимизировать базовый код.



Рисунок 1. Отслеживание сетевого трафика. Модель сетевого трафика предполагает, что эффективность может быть значительно повышена за счет предварительной выборки запросов или объединения загрузок.

Отслеживая частоту передачи данных и объем данных, передаваемых во время каждого соединения, вы можете определить области вашего приложения, которые можно сделать более эффективными с точки зрения расхода батареи. Как правило, вы будете искать короткие всплески, которые можно отложить.

Чтобы лучше определить причину пиков передачи, API Traffic Stats позволяет вам помечать передачи данных, происходящие из сокета в заданном потоке, с помощью TrafficStats.setThreadStatsTag() . Вызов этой функции не помечает автоматически весь трафик для определенного потока; теги должны быть применены к сокетам.

После установки тега потока вы можете вручную помечать и снимать теги с отдельных сокетов с помощью TrafficStats.tagSocket() и TrafficStats.untagSocket() . Тег также применяется, если сокет открыт в потоке или если сокет сервера принимает соединение.

Одновременный доступ к одному и тому же сокету несколькими потоками будет использовать любой тег, который был у сокета на момент отправки или получения сетевых пакетов (который может отличаться от того, когда пользователь записывал или считывал данные, из-за буферизации и повторных передач).

Например, вы можете определить константы для представления различных типов сетевого трафика, как показано в следующем примере кода:

Котлин

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

Ява

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)

Ява

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()
    }
}

Ява

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 .