2015-07-02 9 views
5

Nella mia app di sostituzione della schermata iniziale, devo ottenere un elenco di tutte le app installate per inserirle nel cassetto delle app. Quindi, il seguente metodo viene eseguito su ogni app;Perché resolveInfo.loadLabel() è così ridicolmente lento?

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; 
} 

Il problema è che c'è un collo di bottiglia qui, e non è che il caricamento delle icone come avevo originariamente previsto. La prima riga del metodo (String label = resInf.loadLabel (pacMan).toString();) può occupare ovunque tra 0 e 250 millisecondi (su un dispositivo relativamente di fascia alta). Su dispositivi precedenti, questo diventa un vero problema.
Nei miei test, ho notato che quando un dispositivo più lento esegue il multitasking e per qualche motivo il caricatore delle app deve essere ricaricato, può richiedere fino a 30 secondi per completare questa azione (su tutte le app installate).

Il caching potrebbe offrire una soluzione potenziale per questo, ma che succede se il nome di un'app cambia (cosa che accade occasionalmente)? Dovrei prendere le etichette dalla cache, quindi ricorrere al loop su tutte le app in un thread separato e correggere le etichette in cui sono state modificate. Questo può offrire una soluzione, ma sembra più un trucco sporco che una vera e propria soluzione.

Esiste un modo più rapido per ottenere l'etichetta dell'attività di un'app? Inoltre, perché ci vuole così tanto tempo per Android per ottenere l'etichetta di un'app e/o c'è qualcosa che posso fare al riguardo?

+1

"e se il nome di un'app cambia (cosa che accade occasionalmente)?" - ascolta le trasmissioni pertinenti e aggiorna la cache per la modifica del nome specifico. Tale modifica si verifica solo quando le app vengono installate, aggiornate o rimosse. "Perché ci vuole così tanto tempo per Android per ottenere l'etichetta di un'app" - Non ho visto questo comportamento. Stai usando Traceview per determinare che questo è esattamente dove si trova il tuo problema? – CommonsWare

+0

@CommonsWare Non ricevo tali trasmissioni solo mentre la mia app è in esecuzione? Si tratta di ottenere l'elenco iniziale delle app installate, di cui ho bisogno quando viene avviata la mia app. Le mie osservazioni provenivano da una (un po 'antiquata, forse) comaprison di timestamp tra quando è iniziata un'azione e quando è stata completata ^^ Ho appena controllato tramite Traceview e mi mostra la stessa conclusione. Questa è la prima volta che utilizzo Traceview, comunque. Quindi, per favore, scusami se sto interpretando male i risultati. http://stuff.robinj.be/stackoverflow/31188658-AsyncLoadApps.trace – RobinJ

+0

"Non ricevo tali trasmissioni solo mentre la mia app è in esecuzione?" -- sì. Dovresti aggiornare queste informazioni all'avvio del processo. "Si tratta di ottenere l'elenco iniziale delle app installate, di cui ho bisogno quando viene avviata la mia app" - si spera che, se si sta scrivendo una schermata principale, si concentri maggiormente sull'acquisizione dell'elenco di attività pubblicabili, non sull'elenco di applicazioni installate app. Non ho riscontrato problemi di prestazioni che descrivono con [il mio esempio di Launchalot] (https://github.com/commonsguy/cw-omnibus/tree/master/Introspection/Launchalot), e quell'esempio è * vecchio *. :-) – CommonsWare

risposta

0

È possibile ottenere etichette come:

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

Se si confronta il codice sorgente di Android per questi due metodi si noterà quello da applicationInfo ha meno codice da eseguire. Forse il collo di bottiglia si trova nel codice aggiuntivo. Personalmente non ho mai confrontato i tempi di esecuzione per quelli che non ho mai osservato tale problema.

+2

Quello che otterrebbe il nome dell'applicazione reale, non l'etichetta dell'attività (launcher), penso. Alcune applicazioni (come Google Drive) hanno più attività. – RobinJ

+0

Sì, restituisce l'etichetta del tag da manifest, non l'etichetta di attività del programma di avvio, ma nella domanda è stata richiesta l'etichetta "app". – mhenryk