Rozwiązywanie problemów z siecią

Ruch w sieci 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 artykułu dowiesz się, jak monitorować i kategoryzować ruch w sieci oraz jak identyfikować i rozwiązywać problemy.

Monitorowanie żądań za pomocą programu profilującego sieci

Użyj programu profilującego sieci, aby śledzić żądania sieciowe aplikacji. Możesz monitorować, jak i kiedy aplikacja przenosi dane, i odpowiednio optymalizować kod źródłowy.



Rysunek 1. Śledzenie ruchu w sieci. Wzorzec ruchu w sieci sugeruje, że wydajność może znacznie zwiększyć się przez pobieranie żądań z wyprzedzeniem lub grupowanie przesyłanych plików.

Monitorując częstotliwość przesyłania i ilość danych przesyłanych podczas każdego połączenia, możesz identyfikować obszary aplikacji, w których można zwiększyć zużycie baterii. Zwykle chodzi o krótkie skoki, które mogą wystąpić z opóźnieniem.

Aby lepiej zidentyfikować przyczyny gwałtownych skoków transferów danych, interfejs Traffic Stats API umożliwia tagowanie za pomocą narzędzia TrafficStats.setThreadStatsTag() przesyłania danych z gniazda w obrębie danego wątku. Wywołanie tej funkcji nie powoduje automatycznego tagowania całego ruchu w danym wątku. Tagi należy zastosować do gniazd.

Po ustawieniu tagu wątku możesz ręcznie dodawać tagi do poszczególnych gniazd za pomocą tagów TrafficStats.tagSocket() i TrafficStats.untagSocket(). Tag jest też stosowany, gdy gniazdo w wątku jest otwarte lub gniazdo serwera akceptuje połączenie.

Równoczesny dostęp do tego samego gniazda przez wiele wątków będzie korzystać z tagu, który znajdował się w gniazdku w momencie wysyłania lub odbierania pakietów sieciowych (który może różnić się od tego, kiedy użytkownik zapisał lub odczytał dane, z powodu buforowania i ponownego przesyłania).

Możesz na przykład zdefiniować stałe reprezentujące różne typy ruchu w sieci, jak pokazano 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;

Następnie możesz odpowiednio otagować żą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 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

Analizując ruch w sieci generowany przez aplikację, musisz poznać jego źródło, aby móc go odpowiednio zoptymalizować. Częsta aktywność w sieci generowana przez aplikację może być całkowicie odpowiednia, jeśli odpowiada na działania użytkownika, ale jest też całkowicie niestosowna, gdy aplikacja nie działa na pierwszym planie albo gdy 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. Twoim celem jest analiza ruchu w sieci inicjowanego przez użytkownika w poszukiwaniu wzorców częstego korzystania z sieci w czasie i próba zmniejszenia ich częstotliwości przez zgrupowanie żą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, gdy użytkownik wchodzi w bezpośrednią interakcję z aplikacją, najważniejsza jest dla niego szybka reakcja, a nie wydajniejsze korzystanie z sieci.

Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez użytkownika znajdziesz w artykule Optymalizacja żądań inicjowanych przez użytkowników.

Analizowanie ruchu inicjowanego 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. Analizując aktywność sieciową Twojej aplikacji, poszukaj okresów braku aktywności i spróbuj je zwiększyć. Jeśli zauważysz wzorce stałego dostępu z aplikacji do sieci, spróbuj zgrupować ten ruch, by radio urządzenia przełączyło się z powrotem w tryb oszczędzania energii między okresami aktywności.

Rekomendacje dotyczące optymalizacji ruchu inicjowanego przez aplikację znajdziesz w artykule Optymalizacja żądań inicjowanych przez aplikację.

Analizowanie ruchu inicjowanego przez serwer

Aktywność sieci inicjowana przez serwery komunikujące się z Twoją aplikacją zwykle też może mieć znaczny wpływ na efektywne wykorzystanie przepustowości sieci. Komunikacja w chmurze Firebase (FCM) to uproszczony mechanizm służący do przesyłania danych z serwera do określonej instancji aplikacji. Dzięki FCM serwer może powiadomić Twoją aplikację działającą na danym urządzeniu, że są 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, aby zwizualizować wpływ ruchu w sieci

Battery Historyn to narzędzie, które wizualizuje wykorzystanie baterii przez urządzenie w określonym czasie. Za pomocą tego narzędzia możesz przeanalizować, jak Twoja aktywność w sieci wpływa 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 korzystaniu z narzędzia Battery Historyn znajdziesz w artykule Profil wykorzystania baterii przy użyciu Batterystats i Battery Historyn.