2015-07-02 27 views
5

W aplikacji do wymiany ekranu głównego muszę uzyskać listę wszystkich zainstalowanych aplikacji, aby umieścić je w szufladzie aplikacji. Dlatego każda metoda uruchamia następującą metodę;Dlaczego metoda resolveInfo.loadLabel() jest tak śmiesznie powolna?

public static App fromResolveInfo (Context context, PackageManager pacMan, AppManager appManager, ResolveInfo resInf) 
{ 
    String label = resInf.loadLabel (pacMan).toString(); 
    String packageName = resInf.activityInfo.applicationInfo.packageName; 
    String activityName = resInf.activityInfo.name; 

    App app = new App (context, appManager); 
    app.setLabel (label); 
    app.setPackageName (packageName); 
    app.setActivityName (activityName); 

    AppIcon icon = null; 
    if (appManager.isIconPackLoaded()) 
     icon = appManager.getIconPack().getIconForApp (app); 
    if (icon == null) 
     icon = appManager.getIconPack().getFallbackIcon (resInf.loadIcon (pacMan)); 

    app.setIcon (icon); 

    return app; 
} 

Problem polega na tym, że istnieje tu wąskie gardło, i to nie on ładuje ikony, jak się początkowo spodziewałem. Pierwsza linia metody (String label = resInf.loadLabel (pacMan).toString();) może zająć od 0 do 250 milisekund (na stosunkowo wysokim urządzeniu końcowym). Na starszych urządzeniach staje się to poważnym problemem.
W swoich testach zauważyłem, że gdy wolniejsze urządzenie działa wielozadaniowo i z jakiegoś powodu należy ponownie załadować aplikację, może to zająć do 30 sekund, aby ta czynność została wykonana (we wszystkich zainstalowanych aplikacjach).

Buforowanie może stanowić potencjalne rozwiązanie tego problemu, ale co się stanie, jeśli zmieni się nazwa aplikacji (co się czasami zdarza)? Będę musiał pobrać etykiety z pamięci podręcznej, a następnie zapętlić wszystkie aplikacje w osobnym wątku i poprawić etykiety tam, gdzie zostały one zmienione. Może to stanowić rozwiązanie, ale wydaje się bardziej jak brudny hak niż rzeczywiste dobre rozwiązanie.

Czy jest jakiś szybszy sposób uzyskania etykiety aktywności aplikacji? Poza tym, dlaczego tak długo trwa uzyskanie przez Androida etykiety aplikacji i/lub czy jest coś, co mogę z tym zrobić?

+1

"co, jeśli zmieni się nazwa aplikacji (co się czasami zdarza)?" - słuchaj odpowiednich audycji i aktualizuj pamięć podręczną, aby zmienić nazwę. Taka zmiana nastąpi tylko wtedy, gdy aplikacje zostaną zainstalowane, zaktualizowane lub usunięte. "Dlaczego tak trudno jest Androidowi zdobyć etykietę aplikacji" - nie widziałem takiego zachowania. Czy korzystasz z Traceview, aby ustalić, że jest to dokładnie miejsce, w którym występuje problem? – CommonsWare

+0

@CommonsWare Czy nie otrzymam takich programów tylko podczas mojej aplikacji? Chodzi o uzyskanie początkowej listy zainstalowanych aplikacji, których potrzebuję, gdy moja aplikacja jest uruchomiona. Moje spostrzeżenia pochodziły od (nieco staroświeckiego, być może) więźniarza znaczników czasu pomiędzy rozpoczęciem i zakończeniem akcji. ^^ Właśnie sprawdziłem przez Traceview i pokazuje mi to samo. Po raz pierwszy korzystam z Traceview. Więc przepraszam, jeśli źle interpretuję wyniki. http://stuff.robinj.be/stackoverflow/31188658-AsyncLoadApps.trace – RobinJ

+0

"Czy nie otrzymam takich emisji tylko podczas mojej aplikacji?" -- tak. Będziesz musiał odświeżyć te informacje po uruchomieniu procesu. "Chodzi o uzyskanie początkowej listy zainstalowanych aplikacji, których potrzebuję, gdy moja aplikacja jest uruchomiona" - mam nadzieję, że jeśli piszesz ekran główny, skupiasz się bardziej na otrzymywaniu listy uruchamialnych działań, a nie na liście zainstalowanych aplikacje. Nie doświadczyłem problemów z wydajnością, które opisujesz za pomocą [mojej próbki Launchalot] (https://github.com/commonsguy/cw-omnibus/tree/master/Introspection/Launchalot), a ta próbka ma * stary *. :-) – CommonsWare

Odpowiedz

0

Można uzyskać etykietę jako:

String label = (String) resInf.activityInfo.applicationInfo.loadLabel(pacMan); 

Jeśli porównać kod źródłowy Androida dla tych dwóch metod można zauważyć jedną z applicationInfo ma mniej kodu do wykonania. Może wąskie gardło znajduje się w dodatkowym kodzie. Osobiście nigdy nie porównywałem czasów wykonania dla tych, których nigdy nie zaobserwowałem.

+2

To by uzyskać nazwę rzeczywistej aplikacji, a nie etykiety działania (launcher), myślę. Niektóre aplikacje (np. Dysk Google) mają wiele działań. – RobinJ

+0

Tak, zwraca etykietę z tagu z manifestu, a nie etykietę aktywności launchera, ale w pytaniu poprosiłeś o "etykietę aplikacji". – mhenryk