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

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

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

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

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



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

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

Чтобы лучше определить причину всплесков передачи, API статистики трафика позволяет помечать передачи данных, происходящие из сокета внутри данного потока, с помощью 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() . Библиотека также помечает и снимает теги сокетов при переработке через пулы поддержки активности, как показано в следующем примере кода:

Котлин

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 .