Optymalizacja aplikacji na Androida przed wydaniem [zamknięte]


120

Jestem w „ szczególnej ” sytuacji związanej z wydajnością mojego programu. Teraz jestem na etapie, w którym muszę poprawić wydajność aplikacji i zmniejszyć zużycie baterii .

Przed pytaniem:

Teraz jestem ciekawy, aby dowiedzieć się o specjalnych poprawkach innych programistów, których użyli do optymalizacji własnych aplikacji. Rzeczy, których użytkownicy mogą nigdy nie rozpoznać lub na które nie zwrócić uwagi. Jednak poprawki albo wydłużą żywotność baterii, albo pomogą usprawnić konserwację aplikacji.

Więc jaka jest twoja unikalna sztuczka optymalizacji?

Jestem w szczególnej sytuacji, w której naprawdę szukam wiedzy i myślę, że będzie to świetna okazja do podzielenia się wiedzą programistów na temat sytuacji, w której wszyscy się znaleźli.

Głosujcie na świetne odpowiedzi, ponieważ zachęcą to świetnych programistów do podzielenia się swoją wiedzą.


2
Ponieważ wydajność ostatecznie sprowadza się do tego, że nie musisz robić niczego, czego nie musisz (lub częściej niż musisz), myślę, że wiele będzie zależeć od tego, jakie typy rzeczy ma wykonać Twoja aplikacja ... Bez określenia tego, wszystko co można zrobić, to zdobyć zbiór „zwykłych podejrzanych”
Chris Stratton,

1
@Chris Stratton: Cóż, masz rację. Ale także „zwykli podejrzani” lub mała odpowiedź na temat określonej sztuczki ułatwią innym podjęcie decyzji, czy to „przypuszczenie” jest tym, czego szukają (i czy jest to przydatne w ich konkretnej sytuacji).
Wroclai

To śmieszne, ile naprawdę interesujących pytań zostało zamkniętych na tej stronie.
Patrick

Przeczytaj ten blogpost medium.com/@hammad_tariq/ ...
Developine

Odpowiedzi:


68

W pewnym momencie dojdziesz do punktu, w którym używanie znanych sztuczek osiągnie swoje granice. Najlepszą rzeczą do zrobienia w tym momencie jest profilowanie kodu i sprawdzenie, które obszary są wąskimi gardłami w oparciu o Twoje konkretne wymagania.

Badanie użycia pamięci RAM za pomocą MAT i Traceview : artykuł o tym, jak używać narzędzi do profilowania aplikacji.


Dzięki! Bardzo lubię odpowiedzi z zasobami. :-)
Wroclai 11.04.11 o

1
Przeczytaj ten post na blogu. medium.com/@hammad_tariq/…
Developine

37

Śledź i ograniczaj przydziały. Im więcej przydzielisz, tym częściej moduł odśmiecania pamięci będzie musiał działać, zatrzymując proces przed wykonywaniem jakichkolwiek innych czynności przez stosunkowo długi czas, na przykład 100 ms.

Najlepszym narzędziem, jakie znam, jest śledzenie alokacji zawarte w DDMS .

Nie tylko GC może mieć wpływ na wrażenia użytkownika, ale zbędne alokacje i GC pochłaniają część zasobów obliczeniowych.

Oto przykład i mała sztuczka. W mojej aplikacji mam zegar, który pokazuje aktualny czas (audio), z uwzględnieniem dziesiątych części sekundy. Jest to często aktualizowane. TextView wykonuje wewnętrzne alokacje za każdym razem, gdy wywołujesz metodę setText () z CharSequence. Ale nie alokuje niczego z wariantem setText (char [] text, int start, int len). Nie jest to udokumentowane i nikt nie odpowiedział, kiedy o to zapytałem.

Takich jest wiele. I to jest jeden z powodów, dla których moja aplikacja zawiera 50% kodu natywnego (ale są też inne powody).

Oprócz tego mogę polecić eksperymentowanie z ProGuard . Wykonuje kilka przejść optymalizacyjnych i rejestruje takie informacje, jak nieużywane metody w projekcie, co może pomóc w usunięciu pozostałości w kodzie.


1
Świetna odpowiedź! Doceniane są konkretne sztuczki.
Wroclai

22

Jeśli Twoja aplikacja będzie miała dużo czasu przed ekranem, używaj czarnego, gdzie tylko możesz . Zmniejszy to zużycie baterii w najgorszej części urządzenia: ekranie, szczególnie w telefonach i tabletach AMOLED.


Rozsądne użycie ciemnych kolorów oznacza wygraną dla baterii.
Robert Massaioli

7
Z drugiej strony czerń na ekranach LCD pobiera więcej energii niż biel, ponieważ światło (z podświetlenia) zaczyna się jako białe i musi być aktywnie blokowane, aby wytworzyć czerń. [ Scientificamerican.com/article.cfm?id=fact-or-fiction-black-is ] Konkluzja: nie licz zbytnio na optymalizację kolorów.
Sparky

16

W przypadku aplikacji z wieloma działaniami sprawdź, czy nie uruchamiasz ponownie działań, które trzeba tylko przenieść na pierwszy plan, używając odpowiednich flag intencji. Sprawdź, czy sterta jest pod kontrolą i czy niepotrzebne widoki, powiązania i konteksty nie są tworzone.

Uważam, że najlepszym narzędziem do pokazania tego wszystkiego podczas działania aplikacji jest:

adb shell dumpsys meminfo 'your apps package name'

1
Och, to było nowe. Dzięki za udostępnienie!
Wroclai

15

Korzystając z SQLlite, należy zwrócić szczególną uwagę na indeksy. Nie zakładaj niczego. Otrzymałem ogromne przyspieszenia w Zwitscher, kiedy umieszczałem indeksy na kolumnach powszechnie używanych do wyszukiwania.


13

Kilka wskazówek, które pomogą Ci zoptymalizować aplikację pod kątem interfejsu użytkownika :

  • użyj convertViewdla adapterów list - byłoby bardzo drogie, gdybyś utworzył nowy widok wewnątrz, Adapter.getView()ponieważ ta procedura jest wywoływana dla każdej pozycji na liście. Użycie convertViewumożliwia ponowne użycie już utworzonego widoku. Dobry przykład (wraz z wykorzystaniem ViewHolder) można znaleźć w ApiDemos .

  • Może się zdarzyć, że układy nie są w pełni zoptymalizowane i można je ulepszyć (na przykład za pomocą scalania lub usuwania elementów nadrzędnych). Układ narzędzia Android znajdzie dla Ciebie taką sytuację. Może być używany z HierarchyViewer do inspekcji poszczególnych widoków. Więcej informacji tutaj .

  • usuń tło do rysowania - framework Androida miał (czy nadal ma?) problem z wykrywaniem widoków do narysowania. Istnieje szansa, że ​​Twoje (domyślne) tło do rysowania zostanie narysowane tylko po to, aby następnie zostać ukryte przez nieprzezroczysty interfejs użytkownika. Aby pozbyć się tego marnotrawnego rysunku, po prostu usuń tło do rysowania.

Można to zrobić za pomocą niestandardowego stylu

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>

Kilka wskazówek, które pomogą Ci zoptymalizować aplikację pod kątem wykorzystania baterii :

  • sprawdź typ sieci i poczekaj, aż użytkownik znajdzie się w obszarze z wifi lub 3G (a nie roamingiem) i dopiero wtedy pozwól mu korzystać z połączenia

  • Jeśli to możliwe, używaj gzip do danych tekstowych, aby przyspieszyć pobieranie i analizowanie

  • przetwarzaj złożone obiekty Java, takie jak XmlPullParserFactory/ BitmapFactory/ StringBuilder/ Matcheritp.

Aby uzyskać więcej sztuczek dotyczących baterii, zobacz Kodowanie na całe życie - to znaczy żywotność baterii .


„przetwarzaj złożone obiekty Java, takie jak ...” Jak? podczas gdy Java ma GC
Yousha Aleayoub

9

Coś do przemyślenia: NIE nadużywaj String, na przykład w ogromnej pętli. Spowoduje to utworzenie wielu obiektów typu String, które będą musiały zostać poddane GC. Przykład „Złe kodowanie” da 2 obiekty łańcuchowe w każdej pętli. W następnym przykładzie zostanie utworzony tylko jeden końcowy ciąg i jeden program budujący ciąg. To robi ogromną różnicę przy optymalizacji dużych pętli pod kątem szybkości. Podczas tworzenia aplikacji Wordlist Pro na Androida często używałem narzędzia stringbuilder i stało się naprawdę szybkie, gdy przechodziłem przez 270000 słów w mgnieniu oka.

    //Bad coding:
    String s = "";
    for(int i=0;i<999999;i++){
        s = "Number=";
        s = s + i;
        System.out.println(s);
    }

    //Better coding
    final String txt = "Number=";
    StringBuilder sb = new StringBuilder();
    for(int i=0;i < 999999;i++){
        sb.setLength(0);
        sb.append(txt);
        sb.append(i);
        System.out.println(sb);
    }

Napisałem na ten temat bardziej rozbudowany wpis na blogu. przeczytaj tutaj


6

Wydaje mi się, że używanie zmiennych „końcowych” wszędzie tam, gdzie jest to możliwe, mogłoby również poprawić szybkość wykonywania.


1
Pamiętam, że gdzieś to czytałem, czy możesz podać link?
Wesley Wiser

1
Nie jestem pewien, czy jest to prawdą w przypadku zmiennych końcowych, ale może tak być w przypadku statycznych zmiennych końcowych - patrz stackoverflow.com/questions/3117770/ ...
Alistair Collins

Nie mogę podać linku, ale spotkałem się z informacją o tym w „Beginners guide to android” Reto Meiera (19 maja 2010) / Google IO. Jest krótki, można go pobrać bezpłatnie i zawiera dobre porady, jak zbudować dobrą aplikację.
Stan

2
Zmienne końcowe mogą uczynić kod bardziej wydajnym, ponieważ będzie to oznaczać, że wszystkie obiekty zostaną poddane GC w tym samym przebiegu. Nie w różnych momentach w zależności od tego, kiedy ustawisz je na zero.
Robert Massaioli,

1
Pytanie: Czy kompilator nie robi tego wyraźnie za Ciebie? Myślę, że powinien to zrobić w fazie analizy kodu.
Pawan

6

Zoptymalizuj swoje obrazy PNG za pomocą narzędzi takich jak OptiPNG i PNGCrush, aby zaoszczędzić kilka (kilogramów) bajtów z rozmiaru APK. Również tutaj mają zastosowanie wskazówki dotyczące optymalizacji obrazu dla witryn internetowych: użyj odpowiednich formatów obrazu, baw się kompresją JPG, rozważ użycie przezroczystości binarnych zamiast 8-bitowych itp.

Jeśli wysyłasz duże pliki PNG z kanałem alfa, możesz zamienić część rozmiaru APK na szybkość uruchamiania i użyć oddzielnych plików JPG dla kanałów RGB i A .

Jeśli tworzysz połączenia HTTP, sprawdź, czy Twój klient HTTP wykorzystuje kompresję treści. Jeśli buforuje otrzymane odpowiedzi HTTP, sprawdź, czy poprawnie rozumie i używa nagłówków HTTP związanych z buforowaniem.


Dzięki za wgląd! Nigdy o tym nie słyszałem!
Wroclai

5

Jeśli masz operacje sieciowe, spróbuj ponownie użyć tej samej instancji httpclient. Unikaj używania wyrażeń regularnych.


Powód? czy możesz mi wytłumaczyć dlaczego?
Yousha Aleayoub

5

Spróbuj użyć DDMS do śledzenia wszystkich wątków uruchomionych w systemie. Na przykład zauważyłem, że używam webview do wyświetlania treści html, zauważyłem, że tworzy kilka wątków do zarządzania sesjami zarządzania plikami cookie itp., Co zwiększa zużycie pamięci. Więc jeśli nie masz poważnej potrzeby wyświetlania złożonego kodu HTML, spróbuj użyć zwykłej klasy narzędzi „Html” w systemie Android, aby wyświetlić zawartość HTML. Może to być przydatne dla osób, które wyświetlają Eula, ponieważ eula zazwyczaj zawiera tekst HTML.

Jeśli musisz wykonywać operacje sieciowe, spróbuj użyć AndroidHttpClient, jeśli jesteś początkującym, ma dobre możliwości buforowania sesji SSL i wszystko to naprawdę pomaga w poprawie wydajności. Zawsze ustawiaj limity czasu połączenia na około 60 sekund lub jakieś skończone wartości, ponieważ nieskończone limity czasu mogą powodować zakleszczenia, zwłaszcza jeśli zrywasz połączenie podczas uzgadniania protokołu SSL.



4

Unikaj używania XPath, jeśli możesz przeanalizować dane wejściowe XML za pomocą procedur manipulowania ciągami, aby uzyskać tekst między tagami. Przetestowałem i mogę potwierdzić 10-krotną poprawę w tym przypadku, na zestawie danych zawierającym 50000 elementów, na HTC Desire.


3

Wiem, że dołączam do tej rozmowy nieco później, ale byłoby idealnie mieć wiele dobrych wskazówek w jednym miejscu, więc mam nadzieję, że ten wątek będzie żył i dość często aktualizowany. Moje wskazówki:

  • Nie blokuj wątku interfejsu użytkownika z kosztownymi zadaniami, użytkownik opuści, jeśli nie ma odpowiedzi z aplikacji (użyj AsyncThreads).
  • Użyj LINT , nowego narzędzia, które skanuje źródła projektów Androida w poszukiwaniu potencjalnych błędów.

..zostanie zaktualizowany ..

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.