Dlaczego aplikacje na Androida zajmują coraz więcej miejsca?

Paweł Dedio Programowanie 2018-12-08

Witajcie ponownie! Dzisiaj chciałbym poruszyć powszechny problem. Pewnie wielokrotnie zastanawialiście się, jak to się dzieje, że niektóre aplikacje zajmują sporo pamięci i na dodatek ich rozmiar stale rośnie. Dzisiaj rozwieję Wasze wątpliwości!

Co to właściwie jest aplikacja?

Na potrzeby tego artykułu wyróżnimy dwa stany aplikacji: przed i po zainstalowaniu. Pewnie nieraz spotkałeś się z plikami w formacie .apk. Są to właśnie aplikacje, które możemy zainstalować na urządzeniu z Androidem. Apk to nic innego jak zwyczajne archiwum, takie jak na przykład archiwum zip. Powstaje ono w momencie kompilacji i zawiera pliki niezbędne do poprawnego uruchomienia każdego programu. Kolejnym stanem jest już aplikacja zainstalowana na urządzeniu — od tego momentu ma ona dostęp do zasobów i z powodzeniem może wykonywać swoje zadania.

Czemu rozmiar pliku apk jest taki ważny?

Nie możemy zrobić dowolnie wielkiej aplikacji. Maksymalny rozmiar pliku apk, jaki może zostać wrzucony do Google Play to 100 MB (przez długi czas limit wynosił 50 MB). Wydaje się, że to dość sporo, jednak wiele aplikacji ma problem ze zmieszczeniem się w tym limicie. Dotyczy to głównie gier, ponieważ mają bardzo rozbudowany interfejs graficzny. W przypadku gdy nasza aplikacja nie mieści się w tym limicie, musimy ją podzielić. Wyróżniamy wtedy główny plik apk oraz dodatkowe pliki niezbędne do rozgrywki. Najczęściej dodatkowe pliki są pobierane w tym samym czasie gdy pobieramy plik apk z Google Play, jednak czasami może się to nie udać. Wtedy po uruchomieniu aplikacji będziemy musieli poczekać, aż wszystkie dodatkowe pliki zostaną pobrane. Cały ten proces jest dość prosty z perspektywy programisty, ponieważ Google udostępnia przyjazne mechanizmy do implementacji takiego zachowania.

Co wpływa na rozmiar pliku apk?

Tak jak wspomniałem na początku, plik apk to nic innego jak archiwum. Żeby Wam to udowodnić, pokażę pewien trik. Otwórzcie jakąś aplikację w internetowej wersji Google Play (ja wybrałem Snapchata) i pobierzcie plik apk, wykorzystując dowolny serwis do ich pobierania (wystarczy wpisać w wyszukiwarce frazę „apk downloader online”). Zmieńcie rozszerzenie pobranego pliku z .apk na .zip i rozpakujcie jak normalne archiwum. Waszym oczom powinien ukazać się widok jak powyżej. Również Android Studio (program, w którym tworzymy aplikacje na Androida) posiada fajne narzędzie do podglądania zawartości plików apk.

Teraz bardzo łatwo możemy zobaczyć, co wpływa na rozmiar pliku apk Snapchata. Najwięcej zajmują dra foldery: lib oraz res.

Po otworzeniu folderu lib widzimy mnóstwo dołączonych bibliotek natywnych. Nie chcę się za bardzo zagłębiać w temat, ponieważ jest on dość obszerny. Na tym etapie wystarczy, żebyś wiedział, że są to biblioteki napisane w języku C lub C++. Jeśli chodzi o Snapchata, to prawdopodobnie chodzi o biblioteki do rozpoznawania twarzy, dzięki czemu możemy sobie dodawać do zdjęcia psie uszy i inne filtry.

Znacznie ciekawszy jest folder res. Pamiętacie odcinek o tworzeniu interfejsu użytkownika? Wspominałem tam, że możemy tworzyć różne interfejsy w zależności od wielkości i rozdzielczości ekranu. Zobaczcie na folder drawable — to folder zawierający grafiki wykorzystywane w aplikacji. Występuje on w bardzo wielu wariantach.

Popatrzcie na przykład na takie cudo: drawable-ldrtl-xxxhdpi-v17, co oznaczają poszczególne elementy?

  • ldrtl layout direction right to left. Są to grafiki przygotowane do interfejsu układanego od prawej strony. Taki interfejs zobaczymy, jeśli przełączymy urządzenie na język, w którym czytamy od prawej strony, na przykład Hebrajski.
  • xxxhdpi — oznacza, że grafiki będą wykorzystywane na ekranach z największym zagęszczeniem pikseli.
  • v17 — oznacza, że obrazki będą wyświetlane tylko na telefonach, które mają zainstalowany system android w wersji 4.2 (Czyli API Level 17) lub wyższej.

Jeśli interesuje Was więcej wariantów, zachęcam do zajrzenia do oficjalnej dokumentacji.

Część z Was pewnie się domyśliła, skąd tak duży rozmiar folderu res. Wszystko przez niepotrzebne duplikowanie grafik. Jeśli chcemy dostosować obrazki pod wiele różnych rozdzielczości, to będziemy zmuszeni do trzymania tego samego obrazka w różnych konfiguracjach. Jest to straszne marnotrawstwo miejsca.

Kolejnymi plikami, które znacząco wpływają na rozmiar, są pliki z rozszerzeniem .dex. Jest to po prostu nasz napisany kod (klasy), skompilowany do formatu czytelnego dla maszyny wirtualnej Androida.

Ostatnim elementem, który wpływa na rozmiar w odczuwalnym stopniu, jest plik, o tajemniczej nazwie resources.arsc. Jest to również dość obszerny temat (poruszę to w odcinku o procesie kompilacji). W skrócie plik ten zawiera informacje o wszystkich kontrolkach i innych elementach interfejsu.

Zawartość pliku resources.arsc aplikacji Snapchat.

Jak zredukować wielkość pliku apk?

O tym, że rozmiar pliku apk jest poważnym problemem, może świadczyć fakt, że Google poświęcił temu osobny artykuł w oficjalnej dokumentacji Androida. Podstawowym krokiem jest usunięcie nieużywanych obrazków oraz layoutów — na szczęście istnieją narzędzia, które informują nas, gdy w projekcie mamy niewykorzystywane poszczególne elementy.

Jednak czynnością, która pozwala najbardziej zmniejszyć rozmiar aplikacji, jest wykorzystywanie tylko i wyłącznie grafiki wektorowej. Skąd tu oszczędność? Przypomnij sobie, w ilu różnych wariantach rozdzielczości występował folder drawable z aplikacji Snapchat. Dzięki wykorzystaniu wektorów możemy tego uniknąć, ponieważ obrazki w takiej formie można dowolnie skalować bez strat na jakości i w rezultacie wystarczy nam jeden obrazek zamiast kilku.

Bardzo ważne jest również ostrożne dobieranie bibliotek (szczególnie tych natywnych). Zawsze warto sobie zadać pytanie, czy dana biblioteka jest na tyle wartościowa, by warto było zgodzić się na zwiększenie objętości naszej aplikacji.

Równie ważną kwestią jest dbanie o kulturę naszego kodu. Pamiętajmy o złotej zasadzie DRY (don’t repeat yourself — nie powtarzaj się) w odniesieniu do kodu aplikacji, jak i również naszych layoutów. Jeśli widzimy, że ten sam kod występuje w kilku miejscach, musimy poważnie rozważyć jego wydzielenie i reużywanie.

Dlaczego rozmiar aplikacji zwiększa się w trakcie użytkowania?

Czasami można zauważyć różnicę już po pierwszym uruchomieniu, aplikacja zajmuje więcej miejsca, niż ważył plik apk. Dzieje się tak dlatego, że pliki znajdujące się w archiwum apk są przeważnie skompresowane i dopiero po instalacji zostają przywrócone do poprzedniej formy. Dodatkowo tak jak wspominałem, aplikacja przy pierwszym uruchomieniu może pobierać dodatkowe dane.

Również często można zauważyć stopniowy przyrost wielkości aplikacji w trakcie normalnego użytkowania. Tutaj największy wpływ mają pliki zapisywane przez aplikację. Pokażę to na przykładzie Instagrama. Pewnie zauważyłeś, że jeśli otworzysz aplikację bez dostępu do internetu, to z powodzeniem możesz przeglądać wcześniej wyświetlone zdjęcia. Dzieje się tak dzięki czemuś, co nazywa się cache — pamięć podręczna. Zasada działania jest dość prosta: za każdym razem, gdy jakiś obrazek zostanie wczytany z internetu, to zostaje również zapisany w lokalnej pamięci aplikacji. Dzięki takiemu rozwiązaniu kolejnym razem możemy wyświetlić taki obrazek natychmiast, nie czekając na pobranie go z internetu.

Oczywiście takie rozwiązanie ma również wadę, szczególnie jeśli mechanizm cache zostanie źle zaimplementowany. Ponownie pokażę to na przykładzie Instagrama. Jeśli aplikacja zapisuje każde wyświetlone zdjęcie, to po pewnym czasie możemy mieć w pamięci zdjęcia, które widzieliśmy na tablicy kilka miesięcy temu. Mało prawdopodobne, że wyświetlimy tak stare obrazki ponownie, dlatego cache po pewnym czasie powinien być czyszczony. Oczywiście nie miałem na celu oczernianie aplikacji Instagrama, bo z tego, co zauważyłem, to tam w trybie offline mamy dostęp tylko do kilku pierwszych zdjęć — tak więc wygląda na to, że cache jest dobrze zaimplementowane. Chciałem tylko zobrazować, na czym polega zła implementacja i jakie niesie ze sobą zagrożenia.

Kolejnym czynnikiem zwiększającym ilość miejsca zajmowanego przez aplikację mogą być wszelkiego rodzaju pliki zapisywane przez aplikację. Przykładowo aplikacja do edycji tekstów może je zapisywać w swojej wewnętrznej pamięci, a nie ogólnodostępnej.

Jak sobie radzić z rosnącymi aplikacjami?

Z perspektywy użytkownika możemy w prosty sposób ujarzmiać takie niesforne aplikacje. Wystarczy raz na jakiś czas wyczyścić całkowicie dane aplikacji — co prawda przeważnie będziemy musieli się zalogować ponownie. Jednak będziemy mieli pewność, że żadne stare dane nie zajmują niepotrzebnie pamięci. Co prawda w Androidzie możemy wyczyścić tylko samą pamięć cache aplikacji, jednak trzeba mieć na uwadze, że to programista decyduje, co zapisuje w normalnej pamięci, a co w cache. Dlatego może się zdarzyć, że wyczyszczenie samego cache nie pomoże tyle, ile pomoże wyczyszczenie całej pamięci. Upewnijcie się również, że przez usunięcie danych aplikacji nie stracicie żadnych ważnych danych, bo ich odzyskanie będzie już niemożliwe.

Dzięki za dzisiaj! Było trochę dłużej niż zwykle, również dla mnie był to bardzo wymagający artykuł i musiałem sobie odświeżyć część wiadomości. Mam nadzieję, że się podobało — w następnym odcinku opiszę frameworki crossplatform, czyli takie, które umożliwiają tworzenie aplikacji jednocześnie na Androida i iOSa. Do zobaczenia!

Zapraszam również na największe w Polsce forum dla programistów Android. Jeśli macie pytania odnośnie do kariery programisty — zapraszam do działu Kariera programowanie. Zachęcam również do przejrzenia działu Praca oraz zlecenia dla programistów — być może to właśnie tam znajdziesz swoją pierwszą pracę.

Poprzednie odcinki:

  1. Typowy dzień pracy programisty
  2. Wady pracy programisty
  3. Zalety pracy programisty
  4. [FAQ] Wszystko, co powinieneś wiedzieć, jeśli interesuje Cię praca programisty
  5. Co mnie zdziwiło w programowaniu?
  6. Motywacje – w jaki sposób nie stracić zapału do programowania?
  7. Jaką firmę wybrać na początku kariery programisty?
  8. Jak wygląda rozmowa o pracę na stanowisko programisty?
  9. Jak zacząć programować?
  10. Skąd czerpać wiedzę o programowaniu?
  11. Początki programowania — jaką technologię wybrać?
  12. Cykl życia aplikacji na Androida — co to takiego?
  13. Jak tworzymy interfejs użytkownika w aplikacjach na Androida?
  14. Jak system Android oszczędza energię?
  15. Jak działają i czym są powiadomienia push w Androidzie?
  16. W jaki sposób aplikacje pobierają dane z zewnętrznych serwisów i czym jest API?
  17. Jak działają pozwolenia w systemie Android?
  18. Śledzenie użytkowników — co wiedzą o nas aplikacje?


  • Krzysiek Roman

    A już myślałem że to zwykłe reklamy tak powiększają

  • Robe

    Co do wagi apk: miałem na Xperii Arc jakiegoś snowboarda, nie pamiętam tytułu. Apk ważyła 700 MB.

  • maxiges

    Tylko nikt nie wspomniał o tym, że środowiska programowania, są coraz pardziej opasłe. Ile gier jest robione w unreal engine. Gra niby 2D a tak naprawdę ma 3 wymiary, ale widzimy tylko 2 i dlatego prosta gra 2d zajmuje 50mb :). Aplikacje się też rozrastaja bo same biblioteki więcej zajmują bo mają więcej dodatków. Oraz więcej grafik czy animacji/gifów

    • davidns

      50? Chyba 500 🙂

  • Robert Yeter

    A czy jak zmienię rozszerzenie z APK na ZIP i coś zmienie w plikach odpowiadających np za interfejs to mogę później spakować do ZIP i zmienić na APK? Czy będzie się program uruchamiał? Czy będzie potrzebna kompilacja? Nie chodzi mi o pliki z kodem

    • Paweł Dedio

      Możesz spróbować, ale obecnie raczej nie będzie to możliwe. Google niedawno ulepszyło nieco proces weryfikacji apk i sprawdza, czy wszystkie pliki są takie same jak w momencie kompilacji.

      • Robe

        A gdyby zmienić podpis?

        • Paweł Dedio

          Są różne narzędzia do ponownej kompilacji aplikacji. Tylko musisz pamiętać, że podczas takiej zmienionej aplikacji nastąpi konflikt i będziesz musiał odinstalować wersję tej aplikacji pochodzącą ze sklepu Play. Nie będziesz też w stanie zaktualizować takiej aplikacji wersją ze Sklepu Play.

  • CezaR

    Ja od dawna cyklicznie czyszczę nie tylko cache ale niektóre aplikacje z całych danych.
    Jeśli chodzi o tytułowe pytanie to odp wydaje sie prosta, co raz więcej pamięci w urządzeniach rozleniwia programistów…. i Tyle w temacie 🙂 po co tyle pisania… 😀