Ruch sieciowy generowany przez aplikację może mieć znaczący wpływ na czas pracy baterii urządzenia. Aby zoptymalizować ten ruch, musisz go zmierzyć i określić jego ź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 artykułu dowiesz się, jak monitorować i kategoryzować ruch w sieci oraz jak identyfikować i rozwiązywać problemy.
Monitorowanie żądań za pomocą profilera sieci
Użyj profilera sieci, aby śledzić żądania sieciowe aplikacji. Możesz monitorować, jak i kiedy aplikacja przesyła dane, oraz odpowiednio optymalizować kod źródłowy.
Rysunek 1. śledzenie ruchu w sieci, Wzorzec ruchu w sieci sugeruje, że efektywność można znacznie zwiększyć, wstępnie pobierając żądania lub łącząc przesyłane pliki.
Monitorując częstotliwość przesyłania danych i ilość danych przesyłanych podczas każdego połączenia, możesz określić obszary aplikacji, w których można zwiększyć oszczędność baterii. Zwykle szukasz krótkich skoków, które mogą być opóźnione.
Aby lepiej identyfikować przyczyny skoków w przesyłaniu danych, interfejs Traffic Stats API umożliwia oznaczanie przesyłania danych z gniazda w danym wątku za pomocą TrafficStats.setThreadStatsTag()
.
Wywołanie tej funkcji nie powoduje automatycznego otagowania całego ruchu w określonym wątku. Tagi muszą być stosowane do gniazd.
Po ustawieniu tagu wątku możesz ręcznie oznaczać i usuwać oznaczenia poszczególnych gniazd za pomocą symboli TrafficStats.tagSocket()
i TrafficStats.untagSocket()
.
Tag jest też stosowany, gdy w wątku zostanie otwarte gniazdo lub gdy gniazdo serwera zaakceptuje połączenie.
Współbieżny dostęp do tego samego gniazda przez wiele wątków będzie używać tagu, który gniazdo miało w momencie wysyłania lub odbierania pakietów sieciowych (może się on różnić od tagu, który był używany, gdy użytkownik zapisywał lub odczytywał dane, ze względu na buforowanie i ponowne przesyłanie).
Możesz na przykład zdefiniować stałe reprezentujące różne typy ruchu w sieci, 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;
Następnie możesz odpowiednio oznaczyć żądania sieciowe:
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 taguje gniazda na podstawie bieżącej wartości TrafficStats.getThreadStatsTag()
. Biblioteka taguje i usuwa tagi z gniazd, gdy są one ponownie wykorzystywane w puli połączeń keep-alive, jak pokazano 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 sieciowego
Analizując ruch w sieci generowany przez aplikację, musisz znać jego źródło, aby móc go odpowiednio zoptymalizować. Częsta aktywność sieciowa generowana przez aplikację może być w pełni uzasadniona, jeśli jest odpowiedzią na działania użytkownika, ale zupełnie nieodpowiednia, jeśli aplikacja nie jest na pierwszym planie lub urządzenie znajduje się w kieszeni lub torebce.
Analizowanie ruchu inicjowanego przez użytkowników
Ruch sieciowy inicjowany przez użytkownika może być efektywnie grupowany, gdy użytkownik wykonuje określone zadanie w aplikacji, lub rozproszony nierównomiernie, gdy użytkownik prosi o dodatkowe informacje, których aplikacja potrzebuje. Analizując ruch sieciowy inicjowany przez użytkowników, szukaj wzorców częstego korzystania z sieci w czasie i staraj się zmniejszyć ich częstotliwość, grupując żądania.
Nieprzewidywalność żądań użytkowników utrudnia optymalizację tego typu wykorzystania sieci w aplikacji. Użytkownicy oczekują też szybkich odpowiedzi, gdy aktywnie korzystają z aplikacji, więc opóźnianie żądań w celu zwiększenia wydajności może pogorszyć wrażenia użytkowników. Gdy użytkownik bezpośrednio korzysta z aplikacji, priorytetem powinna być szybka reakcja na jego działania, a nie efektywne wykorzystanie sieci.
Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez użytkowników znajdziesz w artykule Optymalizowanie żądań inicjowanych przez użytkowników.
Analizowanie ruchu inicjowanego przez aplikacje
Ruch sieciowy inicjowany przez aplikację to zwykle obszar, w którym możesz mieć znaczący wpływ na efektywne wykorzystanie przepustowości sieci. Analizując aktywność sieciową aplikacji, poszukaj okresów bezczynności i sprawdź, czy można je wydłużyć. Jeśli zauważysz, że aplikacja regularnie uzyskuje dostęp do sieci, spróbuj grupować ten ruch, aby radio urządzenia mogło przełączać się z powrotem w tryb niskiego zużycia energii między okresami aktywności.
Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez aplikacje znajdziesz w artykule Optymalizacja żądań inicjowanych przez aplikacje.
Analizowanie ruchu inicjowanego przez serwer
Aktywność sieciowa inicjowana przez serwery komunikujące się z aplikacją to również 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 powiadamiać aplikację działającą na konkretnym urządzeniu o dostępności nowych danych.
Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez serwer znajdziesz w artykule Optymalizowanie żądań inicjowanych przez serwer.
Używanie narzędzia Battery Historian do wizualizacji wpływu ruchu sieciowego
Battery Historian to narzędzie, które wizualizuje zużycie baterii urządzenia w określonym czasie. Za pomocą tego narzędzia możesz analizować, jak aktywność sieciowa wpływa na zużycie baterii. Na przykład Battery Historian może pokazać, czy Twoja aplikacja korzysta z radia komórkowego częściej niż oczekujesz. Więcej informacji o korzystaniu z narzędzia Battery Historian znajdziesz w artykule Profilowanie wykorzystania baterii za pomocą narzędzi Batterystats i Battery Historian.