Optymalizacja dostępu do sieci

Korzystanie z bezprzewodowego radia do przesyłania danych to prawdopodobnie jedno z najpoważniejszych źródeł zużywania baterii przez aplikację. Aby zminimalizować obciążenie baterii związane z aktywnością sieciową, musisz wiedzieć, jak model łączności wpłynie na podstawowy sprzęt radiowy.

W tej sekcji omawiamy maszynę stanu bezprzewodowego radia oraz wyjaśniamy, jak z nią oddziałuje model łączności z aplikacją. Następnie udostępnia kilka metod, które pomagają zminimalizować wpływ zużycia danych przez aplikację na baterię.

Maszyna radiowa

Radio bezprzewodowe na urządzeniu użytkownika ma wbudowane funkcje oszczędzania energii, które pomagają zminimalizować zużycie baterii. Gdy radio bezprzewodowe jest w pełni aktywne, zużywa dużo energii, ale w stanie nieaktywnym lub w trybie czuwania zużywa bardzo mało energii.

Pamiętaj, że radio nie może przejść ze stanu gotowości do w pełni aktywnego połączenia od razu. Po włączeniu radia pojawia się czas oczekiwania. W ten sposób bateria przechodzi ze stanu wyższego poziomu na niższy, by oszczędzać energię, gdy nie jest używana. Jednocześnie stara się zminimalizować opóźnienia związane z „włączaniem” radia.

Stan maszyny w typowym nadajniku sieci 3G składa się z 3 stanów energii:

  • Pełna moc: używana, gdy połączenie jest aktywne. Dzięki temu urządzenie może przesyłać dane z maksymalną szybkością.
  • Niski poziom energii: stan pośredni, który zmniejsza zużycie energii baterii o około 50%.
  • Tryb czuwania: minimalny stan zużywania energii, w którym nie jest aktywne żadne połączenie sieciowe.

Choć stany niskiego i czuwania znacznie zużywają baterię, powodują też znaczne opóźnienia w realizacji żądań sieciowych. Powrót do pełnego zasilania ze stanu niskiego zasilania trwa około 1,5 sekundy, a przejście z trybu czuwania do pełnego zasilania może potrwać ponad 2 sekundy.

Aby zminimalizować czas oczekiwania, maszyna stanu wykorzystuje opóźnienie do opóźnienia przejścia na niższe stany energii. Ilustracja 1. wykorzystywała czasy AT&T dla typowego radia 3G.


Rysunek 1. Typowy bezprzewodowy odbiornik radiowy 3G

Moduł radiowy każdego urządzenia, a zwłaszcza związane z nim opóźnienie przejścia („czas opóźnienia”) i opóźnienie uruchamiania, będą się różnić w zależności od wykorzystywanej technologii bezprzewodowej (3G, LTE, 5G itd.) oraz są definiowane i konfigurowane przez sieć operatora, w której działa urządzenie.

Na tej stronie opisujemy maszynę stanową reprezentatywną dla typowego bezprzewodowego radia 3G opracowane na podstawie danych dostarczonych przez firmę AT&T. Jednak ogólne zasady i wynikające z nich sprawdzone metody mają zastosowanie do wszystkich implementacji radia bezprzewodowego.

Ta metoda jest szczególnie skuteczna w przypadku typowego przeglądania internetu mobilnego, ponieważ zapobiega niepożądanym opóźnieniom podczas przeglądania internetu przez użytkowników. Względnie krótki czas ogonowania sprawia też, że po zakończeniu sesji przeglądania radio może przejść na niższy poziom energii.

Niestety takie podejście może prowadzić do niewydajnych aplikacji w nowoczesnych systemach operacyjnych na smartfony, takich jak Android, gdzie aplikacje działają zarówno na pierwszym planie (gdy ważne jest opóźnienie), jak i w tle (gdzie ważne jest, aby czas pracy na baterii powinien być priorytetem).

Jak aplikacje wpływają na maszynę stanu radia

Za każdym razem, gdy tworzysz nowe połączenie sieciowe, radio włącza się do trybu pełnego zasilania. W przypadku opisanego wcześniej typowego urządzenia radiowego 3G będzie ono pozostawać w pełni naładowane przez cały czas transferu (plus dodatkowe 5 sekund), a potem przez 12 sekund w stanie niskiego zużycia energii. W przypadku typowego urządzenia 3G każda sesja przesyłania danych powoduje, że radio pobiera energię na co najmniej 18 sekund.

W praktyce oznacza to, że aplikacja wykonująca przesyłanie danych przez jedną sekundę, trzy razy na minutę, będzie utrzymywać bezprzewodowe połączenie radiowe bez przerwy, przenosząc je z powrotem na tryb gotowości.


Rysunek 2. Względne zużycie energii bezprzewodowej do przesyłania danych przez 1 sekundę odbywa się 3 razy na minutę. Rysunek nie uwzględnia czasu oczekiwania na włączenie zasilania między uruchomieniami.

Jeśli ta sama aplikacja będzie przesyłać dane w pakiecie, co minutę przesyłanie danych będzie odbywać się co 3 sekundy, co spowoduje, że na minutę połączenie wystarczy na 20 sekund. Dzięki temu radio może pozostawać w trybie gotowości przez 40 sekund na minutę, co znacząco zmniejszy zużycie baterii.


Rysunek 3. Względne zużycie energii radiowej na potrzeby 3-sekundowych transferów co minutę.

Techniki optymalizacji

Wiesz już, jak dostęp do sieci wpływa na żywotność baterii. Teraz porozmawiamy o tym, co możesz zrobić, aby szybciej i bezproblemowo korzystać z baterii.

Przesyłanie danych w pakiecie

Jak wspomnieliśmy w poprzedniej sekcji, jednym z najlepszych sposobów na oszczędzanie baterii jest łączenie transferów danych w taki sposób, aby rzadziej przenosiły one dane.

Oczywiście nie zawsze jest to możliwe, jeśli aplikacja musi natychmiast otrzymać lub wysłać dane w odpowiedzi na działanie użytkownika. Możesz temu zapobiec, prognozując i wstępując pobieranie danych. Inne scenariusze, takie jak wysyłanie logów lub analiz na serwer czy inne, mniej pilne przesyłanie danych inicjowane przez aplikację, bardzo dobrze nadają się do grupowania i łączenia w pakiety. Wskazówki dotyczące planowania przesyłania sieci w tle znajdziesz w artykule Optymalizowanie zadań inicjowanych przez aplikację.

Wstępnie pobieraj dane

Wstępne pobieranie danych to kolejny skuteczny sposób zmniejszenia liczby niezależnych sesji przenoszenia danych rozpoczętych przez Twoją aplikację. Dzięki pobieraniu z wyprzedzeniem, gdy użytkownik wykona działanie w aplikacji, aplikacja przewiduje, jakie dane będą najprawdopodobniej potrzebne w kolejnej serii działań i pobiera je w ramach pojedynczej serii w ramach pojedynczego połączenia z pełną wydajnością.

Zobowiązując się do przesyłania danych z wyprzedzeniem, zmniejszasz liczbę aktywacji radiowych potrzebnych do pobrania danych. W rezultacie możesz nie tylko wydłużyć czas pracy na baterii, ale także skrócić czas oczekiwania, zmniejszyć wymaganą przepustowość i skrócić czas pobierania.

Pobieranie z wyprzedzeniem poprawia również wygodę użytkowników, ponieważ minimalizuje czas oczekiwania na zakończenie pobierania przed wykonaniem działania lub wyświetleniem danych.

Oto praktyczny przykład.

Czytnik wiadomości

Wiele aplikacji z wiadomościami próbuje zmniejszyć przepustowość, pobierając nagłówki dopiero po wybraniu kategorii, pełne artykuły tylko wtedy, gdy użytkownik chce je przeczytać, a miniatury – tak jak przewijają je użytkownicy.

Przy takim podejściu radio musi być aktywne przez większość sesji czytania wiadomości, gdy przewijają nagłówki, zmieniają kategorie i czytają artykuły. Co więcej, ciągłe przełączanie między stanami energii powoduje znaczne opóźnienie przy przełączaniu kategorii lub odczytywaniu artykułów.

Lepszym podejściem jest pobranie z wyprzedzeniem odpowiedniej ilości danych na początku, na początek z pierwszym zestawem nagłówków i miniatur wiadomości – z myślą o krótkim czasie uruchomienia. Kontynuuj z pozostałymi nagłówkami i miniaturami, a także treścią każdego artykułu dostępną co najmniej z głównej listy nagłówków.

Innym rozwiązaniem jest pobieranie z wyprzedzeniem wszystkich nagłówków, miniatur, tekstów artykułów, a prawdopodobnie nawet całych zdjęć artykułów – zwykle w tle zgodnie z ustalonym harmonogramem. Takie podejście wymaga sporego wykorzystania przepustowości i czasu pracy na baterii, co może spowodować pobieranie treści, które nie są nigdy używane, dlatego powinna być wdrażana z rozwagą.

Dodatkowe uwarunkowania

Chociaż pobieranie danych z wyprzedzeniem przynosi wiele korzyści, to używanie zbyt agresywnego wstępnego wczytywania zwiększa też ryzyko zwiększenia obciążenia baterii i wykorzystania przepustowości (a także limitu pobierania), ponieważ pobiera dane, które nie są używane. Ważne jest też, aby upewnić się, że pobieranie z wyprzedzeniem nie opóźni uruchomienia aplikacji, gdy aplikacja czeka na zakończenie pobierania z wyprzedzeniem. W kontekście praktycznym może to oznaczać stopniowe przetwarzanie danych lub inicjowanie kolejnych transferów w taki sposób, aby w pierwszej kolejności dane potrzebne do uruchomienia aplikacji były pobierane i przetwarzane.

Tempo pobierania danych z wyprzedzeniem zależy od ich rozmiaru i prawdopodobieństwa ich wykorzystania. W przybliżeniu, zgodnie z opisanym wcześniej mechanizmem stanu, w przypadku danych, które mają 50% szans na wykorzystanie w trakcie bieżącej sesji użytkownika, można zwykle pobierać z wyprzedzeniem dane przez około 6 sekund (około 1–2 megabajty), zanim potencjalny koszt pobrania nieużywanych danych będzie się zgadzać z potencjalnymi oszczędnościami wynikającymi z braku pobierania danych.

Ogólnie rzecz biorąc, dobrze jest pobierać dane z wyprzedzeniem, by powtarzać je co 2–5 minut i od 1 do 5 megabajtów.

Zgodnie z tą zasadą duże pliki do pobrania, np. pliki wideo, powinny być pobierane w regularnych odstępach czasu (co 2–5 minut) we fragmentach, co skutecznie pobiera z wyprzedzeniem tylko te dane, które mogą zostać wyświetlone w ciągu najbliższych kilku minut.

Jednym z rozwiązań jest zaplanowanie pełnego pobierania tylko wtedy, gdy urządzenie ma połączenie z Wi-Fi, lub tylko wtedy, gdy urządzenie się ładuje. Interfejs WorkManager API spełnia właśnie ten przypadek użycia i umożliwia ograniczenie działania w tle, dopóki urządzenie nie spełni kryteriów określonych przez dewelopera, takich jak ładowanie czy połączenie z Wi-Fi.

Przed wysłaniem żądań sprawdź połączenie

Wyszukiwanie sygnału komórkowego to jedna z najbardziej pochłaniających energię urządzeń mobilnych. Sprawdzoną metodą w przypadku żądań inicjowanych przez użytkownika jest sprawdzenie połączenia za pomocą narzędzia ConnectivityManager, jak opisano w sekcji Monitorowanie stanu połączenia i pomiaru połączeń. Jeśli nie ma sieci, aplikacja może oszczędzać baterię, nie wymuszając wyszukiwania przez radio w telefonie. Żądanie można zaplanować i wykonać w grupie z innymi żądaniami po nawiązaniu połączenia.

Połączenia basenu

Dodatkową strategią, która może być pomocna poza grupowaniem i pobieraniem z wyprzedzeniem, jest łączenie połączeń sieciowych aplikacji.

Ponowne wykorzystanie istniejących połączeń sieciowych jest zwykle efektywniejsze niż inicjowanie nowych. Ponowne wykorzystywanie połączeń umożliwia też bardziej inteligentniejsze reagowanie na zatory i związane z nimi problemy z danymi.

HttpURLConnection i większość klientów HTTP, takich jak OkHttp, domyślnie włącza pulę połączeń i używa tego samego połączenia w przypadku wielu żądań.

Podsumowanie i plany na przyszłość

W tej części omówiliśmy sporo informacji na temat bezprzewodowego radia oraz pewne strategie, które możesz zastosować, aby zapewnić szybkie i odpowiednie wrażenia użytkownika oraz jednocześnie zmniejszyć zużycie baterii.

W następnej sekcji przyjrzymy się 3 różnym typom interakcji sieciowych, które są typowe dla większości aplikacji. Poznasz czynniki zwiększające skuteczność tych interakcji oraz nowoczesne techniki i interfejsy API.