Ruch w sieci generowany przez aplikację może mieć znaczący wpływ na czas pracy urządzenia na baterii. 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 aplikacji lub z serwera komunikującego się z aplikacją.
W tym artykule dowiesz się, jak monitorować i kategoryzować ruch w sieci, oraz znajdziesz wskazówki dotyczące identyfikowania i rozwiązywania problemów.
Monitorowanie żądań za pomocą narzędzia Network Profiler
Aby śledzić żądania sieciowe aplikacji, użyj narzędzia Network Profiler. 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 grupują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 warto szukać krótkich skoków, które mogą być opóźnione.
Aby ułatwić identyfikowanie przyczyn skoków transferu, interfejs Traffic Stats API umożliwia oznaczanie tagami transferów danych z gniazda w danym wątku za pomocą metody TrafficStats.setThreadStatsTag().
Wywołanie tej funkcji nie powoduje automatycznego otagowania całego ruchu w danym wątku. Tagi muszą zostać zastosowane do gniazd.
Po ustawieniu tagu wątku możesz ręcznie tagować i odtagowywać poszczególne gniazda za pomocą poleceń TrafficStats.tagSocket() i TrafficStats.untagSocket().
Tag jest też stosowany, gdy w wątku zostanie otwarte gniazdo lub gdy gniazdo serwera zaakceptuje połączenie.
Jednoczesny dostęp do tego samego gniazda przez wiele wątków będzie używać tagu, który gniazdo miało w momencie wysłania lub odebrania pakietów sieciowych (co może się różnić od momentu, w którym użytkownik zapisał lub odczytał dane, ze względu na buforowanie i retransmisje).
Możesz na przykład zdefiniować stałe reprezentujące różne typy ruchu w sieci, jak w tym przykładowym kodzie:
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 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ń utrzymujących 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ć jego źródło, aby móc go odpowiednio zoptymalizować. Częsta aktywność sieciowa generowana przez aplikację może być całkowicie uzasadniona, jeśli jest odpowiedzią na działania użytkownika, ale zupełnie nieuzasadniona, jeśli aplikacja nie działa na pierwszym planie lub urządzenie znajduje się w kieszeni lub torebce.
Analizowanie ruchu inicjowanego przez użytkowników
Ruch w sieci zainicjowany przez użytkownika może być skutecznie grupowany, gdy użytkownik wykonuje określone zadanie w aplikacji, lub rozłożony nierównomiernie, gdy użytkownik prosi o dodatkowe informacje, które aplikacja musi uzyskać. Celem analizy ruchu w sieci zainicjowanego przez użytkownika jest znalezienie wzorców częstego korzystania z sieci w czasie i próba zmniejszenia ich częstotliwości przez grupowanie żądań.
Nieprzewidywalność żądań użytkowników utrudnia optymalizację tego typu wykorzystania sieci w aplikacji. Ponadto użytkownicy oczekują szybkich odpowiedzi, gdy aktywnie korzystają z aplikacji, więc opóźnianie żądań w celu zwiększenia wydajności może prowadzić do pogorszenia wrażeń użytkowników. Ogólnie rzecz biorąc, gdy użytkownik bezpośrednio korzysta z aplikacji, priorytetem powinna być szybka odpowiedź, a nie efektywne wykorzystanie sieci.
Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez użytkowników znajdziesz w sekcji Optymalizowanie żądań inicjowanych przez użytkowników.
Analizowanie ruchu inicjowanego przez aplikację
Ruch w sieci 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 braku aktywności i sprawdź, czy można je wydłużyć. Jeśli zauważysz, że aplikacja regularnie uzyskuje dostęp do sieci, spróbuj połączyć ten ruch w pakiety, aby umożliwić urządzeniu przełączanie się z powrotem w tryb oszczędzania baterii między okresami aktywności.
Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez aplikacje znajdziesz w sekcji Optymalizowanie żą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. Dzięki FCM Twój serwer może powiadomić aplikację działającą na konkretnym urządzeniu, że są dostępne nowe dane.
Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez serwer znajdziesz w sekcji Optymalizowanie żądań inicjowanych przez serwer.
Wizualizacja wpływu ruchu w sieci za pomocą narzędzia Battery Historian
Battery Historian to narzędzie, które wizualizuje zużycie baterii urządzenia w określonym czasie. Za jego pomocą możesz analizować wpływ aktywności sieciowej 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 Battery Historian znajdziesz w artykule Profilowanie wykorzystania baterii za pomocą narzędzi Batterystats i Battery Historian.