Rozwiązywanie problemów z siecią

Ruch w sieci generowany przez aplikację może mieć duży wpływ na żywotność 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ą.

W tym temacie dowiesz się, jak monitorować i klasyfikować ruch w sieci oraz jak identyfikować i rozwiązywać problemy.

Używanie programu profilującego sieci do monitorowania żądań

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



Rysunek 1. Śledzę ruch w sieci. Wzorzec ruchu w sieci sugeruje, że wydajność można znacznie poprawić przez wstępne pobieranie żądań lub łączenie przesyłanych danych w pakiety.

Monitorując częstotliwość przesyłania danych i ilość danych przesyłanych podczas każdego połączenia, możesz zidentyfikować obszary swojej aplikacji, które można usprawnić i w ten sposób ograniczyć zużycie baterii. Zasadniczo chodzi o krótkie skoki, które mogą wystąpić z opóźnieniem.

Aby lepiej zidentyfikować przyczynę gwałtownych skoków liczby transferów, interfejs Traffic Stats API umożliwia tagowanie transferów danych realizowanych 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 należy zastosować do gniazd.

Po ustawieniu tagu wątku możesz ręcznie dodawać tagi do poszczególnych gniazd i usuwać z nich tagi, używając parametrów TrafficStats.tagSocket() i TrafficStats.untagSocket(). Tag jest też stosowany wtedy, gdy gniazdo jest otwarte w wątku lub gdy gniazdo serwera akceptuje połączenie.

Równoczesny dostęp do tego samego gniazda w wielu wątkach powoduje wykorzystanie tagu użytego w gnieździe w momencie wysłania lub odebrania pakietów sieciowych (który może być inny niż czas zapisu lub odczytu danych przez użytkownika ze względu na buforowanie i ponowne przesyłanie).

Możesz np. zdefiniować stałe odpowiadające różnym typom 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 oznacza gniazda na podstawie bieżącej wartości TrafficStats.getThreadStatsTag(). Biblioteka oznacza też i usuwa tagi gniazdek w przypadku recyklingu w pulach utrzymujących aktywność, 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 w sieci

Gdy analizujesz 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ć w pełni odpowiednia, jeśli reaguje na działania użytkownika, ale zupełnie nieodpowiednia, jeśli aplikacja nie działa na pierwszym planie albo urządzenie znajduje się w kieszeni lub torebce.

Analizowanie ruchu inicjowanego przez użytkownika

Ruch w sieci inicjowany przez użytkownika można efektywnie zgrupować, gdy użytkownik wykonuje określone zadanie w aplikacji, lub rozłożyć nierównomiernie, gdy użytkownik zażąda dodatkowych informacji, które musi uzyskać aplikacja. Twoim celem analizy ruchu w sieci inicjowanego przez użytkownika jest znalezienie wzorców częstego korzystania z sieci w czasie i spróbowanie zmniejszenia częstotliwości tych żądań przez grupowanie żądań.

Nieprzewidywalność żądań użytkowników utrudnia optymalizację tego rodzaju korzystania z sieci w aplikacji. Poza tym użytkownicy oczekują szybkich odpowiedzi, gdy aktywnie korzystają z aplikacji, więc opóźnienie żądań związanych z wydajnością może obniżyć ich komfort. Ogólnie rzecz biorąc, należy skupić się na szybkiej reakcji użytkownika, a nie na skutecznym korzystaniu z sieci, gdy użytkownik wchodzi w bezpośrednią interakcję z aplikacją.

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

Analizowanie ruchu generowanego 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ą swojej aplikacji, poszukaj okresów nieaktywności i określ, czy można je wydłużyć. Jeśli zauważysz wzorce stałego dostępu do sieci z aplikacji, zgrupuj ten ruch, aby umożliwić komunikację radiową urządzenia z powrotem w tryb oszczędzania energii między okresami aktywności.

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

Analizowanie ruchu inicjowanego przez serwer

Aktywność w sieci inicjowana przez serwery komunikujące się z Twoją 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 prosty mechanizm służący do przesyłania danych z serwera do określonej instancji aplikacji. Za pomocą FCM serwer może powiadamiać aplikację działającą na konkretnym urządzeniu, że są dostępne nowe dane na jego temat.

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

Użyj usługi Battery Historyn, aby zwizualizować wpływ ruchu sieciowego

Historia baterii to narzędzie, które wizualizuje zużycie baterii przez urządzenie w określonym czasie. Możesz użyć tego narzędzia, aby przeanalizować, jak aktywność w sieci wpływa na zużycie baterii. Na przykład Battery Historyn może wskazać, czy aplikacja używa radia komórkowego częściej, niż się spodziewasz. Więcej informacji o korzystaniu z usługi Battery Historyn znajdziesz w artykule o profilowaniu zużycia baterii w narzędziach Batterystats i Historyn.