Ruch sieciowy generowany przez aplikację może mieć znaczny wpływ na czas pracy baterii urządzenia. Aby zoptymalizować ten ruch, musisz go mierzyć i zidentyfikować źródło. Żądania sieciowe mogą pochodzić bezpośrednio z działania użytkownika, z kodu Twojej aplikacji lub z serwera komunikującego się z aplikacją.
Z tego tematu dowiesz się, jak monitorować i kategoryzować ruch sieciowy oraz jak identyfikować i rozwiązywać problemy.
Monitorowanie żądań za pomocą narzędzia Network Profiler
Aby śledzić żądania sieciowe aplikacji, użyj Profilatora sieci. Możesz sprawdzać, jak i kiedy aplikacja przesyła dane, oraz odpowiednio optymalizować kod źródłowy.
Rysunek 1. śledzenie ruchu sieciowego, Wzór ruchu w sieci sugeruje, że można znacznie zwiększyć wydajność, pobierając żądania w ramach wstępnego pobierania lub grupowania przesyłań.
Monitorując częstotliwość przesyłania danych i ich ilość podczas każdego połączenia, możesz określić obszary aplikacji, które można zoptymalizować pod kątem oszczędzania baterii. Zazwyczaj szukasz krótkich pików, które mogą być opóźnione.
Aby lepiej zidentyfikować przyczynę wzrostu transferu, interfejs Traffic Stats API umożliwia oznaczanie tagami transferów danych pochodzących z gniazda w ramach danego wątku za pomocą parametru TrafficStats.setThreadStatsTag()
.
Wywołanie tej funkcji nie powoduje automatycznego tagowania całego ruchu w danym wątku. Tagi należy zastosować do gniazd.
Po ustawieniu etykiety wątku możesz ręcznie oznaczać i usuwać etykiety poszczególnych gniazd za pomocą TrafficStats.tagSocket()
i TrafficStats.untagSocket()
.
Tag jest też stosowany, jeśli gniazdo jest otwarte na wątku lub jeśli gniazdo serwera akceptuje połączenie.
Równoczesny dostęp do tego samego gniazda przez wiele wątków będzie używać tagu gniazda, który był używany podczas wysyłania lub odbierania pakietów sieciowych (co może być inne niż w przypadku zapisywania lub odczytywania danych przez użytkownika z powodu buforowania i przesyłania ponownie).
Możesz na przykład zdefiniować stałe, które będą reprezentować różne typy ruchu sieciowego, jak pokazano w tym przykładzie kodu:
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;
Możesz wtedy odpowiednio oznaczać żądania sieci:
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);
Biblioteka HttpURLConnection
automatycznie oznacza gniazda na podstawie bieżącej wartości TrafficStats.getThreadStatsTag()
. Biblioteka również taguje i usuwa tagi gniazd w przypadku recyklingu przez pule podtrzymujące aktywność, jak w tym przykładowym kodzie:
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(); } }
Analizowanie typów ruchu w sieci
Gdy analizujesz ruch w sieci generowany przez aplikację, musisz znać źródło tego ruchu, aby móc go odpowiednio zoptymalizować. Częste działanie w sieci generowane przez aplikację może być całkowicie odpowiednie, jeśli jest ono reakcją na działania użytkownika, ale może być też całkowicie nieodpowiednie, jeśli aplikacja nie jest na pierwszym planie lub jeśli urządzenie jest w kieszeni lub torebce.
Analizowanie ruchu inicjowanego przez użytkownika
Ruch w sieci inicjowany przez użytkownika może być skutecznie grupowany, gdy użytkownik wykonuje określone zadanie w aplikacji, lub rozkładać się nierównomiernie, gdy użytkownik prosi o dodatkowe informacje, których potrzebuje aplikacja. Celem analizowania ruchu w sieci inicjowanego przez użytkownika jest wyszukiwanie w czasie wzorców częstego korzystania z sieci i próba zmniejszenia ich częstotliwości przez grupowanie żądań.
Nieprzewidywalność żądań użytkowników utrudnia optymalizację tego typu wykorzystania sieci w aplikacjach. Poza tym użytkownicy oczekują szybkich odpowiedzi, gdy aktywnie korzystają z aplikacji, więc zwlekanie z zapytaniami o wydajność może negatywnie wpłynąć na ich wrażenia. Ogólnie rzecz biorąc, szybsza reakcja na użytkownika jest ważniejsza od efektywnego wykorzystania sieci, gdy użytkownik bezpośrednio wchodzi w interakcję z aplikacją.
Zalecenia dotyczące optymalizacji ruchu wywołanego przez użytkownika znajdziesz w artykule Optymalizacja żądań wywoływanych przez użytkownika.
Analizowanie ruchu wywołanego przez aplikację
Ruch w sieci inicjowanej przez aplikację to zwykle obszar, w którym może to znacząco wpływać na efektywne wykorzystanie przepustowości sieci. Podczas analizowania aktywności w sieci Twojej aplikacji poszukaj okresów bezczynności i sprawdź, czy można je wydłużyć. Jeśli zauważysz w swojej aplikacji wzorce stałego dostępu do sieci, spróbuj grupować ten ruch, aby umożliwić radioodbiornikom na urządzeniu przełączenie się z pomiędzy okresami aktywności w tryb niskiego zużycia energii.
Rekomendacje dotyczące optymalizacji ruchu wywołanego przez aplikację znajdziesz w artykule Optymalizacja żądań wywołanych przez aplikację.
Analizowanie ruchu inicjowanego przez serwer
Aktywność sieciowa inicjowana przez serwery komunikujące się z Twoją aplikacją to też zazwyczaj obszar, w którym możesz mieć znaczący wpływ na efektywne wykorzystanie przepustowości sieci. Komunikacja w chmurze Firebase (FCM) to lekki mechanizm służący do przesyłania danych z serwera do konkretnej instancji aplikacji. Za pomocą FCM serwer może powiadomić aplikację działającą na konkretnym urządzeniu, że są dla niej dostępne nowe dane.
Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez serwer znajdziesz w artykule Optymalizacja żądań inicjowanych przez serwer.
Użyj narzędzia Battery Historyn do wizualizacji wpływu ruchu w sieci
Historia baterii to narzędzie, które wizualizuje zużycie baterii urządzenia w danym okresie. Za pomocą tego narzędzia możesz analizować wpływ aktywności w sieci na zużycie baterii. Na przykład Battery Historyn może pokazać, czy Twoja aplikacja używa sieci komórkowej częściej, niż się spodziewasz. Więcej informacji o używaniu Battery Historian znajdziesz w artykule Profilowanie wykorzystania baterii za pomocą Batterystats i Battery Historian.