2010-02-03 12 views
7

Sto creando un'app per Android, nella mia attività ho bisogno di caricare un array di circa 10000 stringhe. Il caricamento dal database era lento, quindi ho deciso di inserirlo direttamente in un file .java (come campo privato). Ho circa 20 di queste classi contenenti array di stringhe e la mia domanda è, sono tutte le classi caricate in memoria dopo l'avvio della mia applicazione? In tal caso, l'attività in cui ho bisogno di queste stringhe verrà caricata rapidamente, ma l'applicazione nel suo complesso avrebbe un avvio lento ... C'è altro modo, come caricare molto rapidamente un array di stringhe 10000 da un file?Tutti i file .class nella mia applicazione Java sono caricati in memoria dopo l'avvio dell'appliaction?

UPDATE: Perché ho bisogno di queste stringhe? La mia app per Android ti consente di trovare "viaggi" nel trasporto pubblico di Praga: scegli la fermata di partenza, la fermata di arrivo e trova il tuo viaggio (dai uno sguardo allo here). La mia app ha una funzione di suggerimenti: inserisci leter "c" come fermata di partenza e un suggerimento ListView appare con arresti che iniziano con "c". Per questi suggerimenti ho bisogno delle stringhe. Il recupero dei suggerimenti dal database è lento (circa 400ms su G1).

+0

A cosa servono queste stringhe? – Macarse

+0

La maggior parte dei dispositivi Android è affamata di memoria principale, se possibile genererei quelle stringhe al volo. –

+0

Se li stai visualizzando in un elenco, ListView + CursorAdapter li caricherà al volo, molto velocemente. Non dovresti avere problemi di prestazioni con SQLite su Android per un caso così semplice. –

risposta

4

Innanzitutto, 400 ms per eseguire una query di database semplice è molto lento. Così lento che sospetto che ci sia qualche problema nello schema del database (ad esempio indici) o nella configurazione della connessione al database.

Ma se un serio circa non utilizzando un database, ci sono un paio di alternative a ciò che si sta facendo:

  1. Disporre che le classi che contengono gli array vengono pigramente caricati come richiesto, utilizzando Class.forName(...) . Se lo si implementa correttamente, dovrebbe essere possibile per il garbage collector recuperare le classi dopo che sono state caricate e le stringhe sono state aggiunte alla struttura dati primaria.

  2. Trasforma le 10000 stringhe in un file flat, inserisci il file nel file JAR dell'app. Quindi utilizzare Class.getResourceAsStream(...) per aprire il file e leggerlo nell'array in memoria.

  3. Come sopra, ma utilizzando un file indicizzato e sostituendo l'array con una struttura dati che consente di leggere le stringhe dal file pigramente. (Questo sarà un po 'complicato, ma se sei preoccupato per la memoria consumata dalle stringhe 10000, questo ti aiuterà a risolverlo.)

+0

Grazie, ora sto usando Class.forName ("") ed è molto veloce. – fhucho

3

Una classe viene caricata solo al primo riferimento.

Sebbene sia necessario un array di 10000, potrebbe non essere necessario tutto in una volta. Qui è dove entra in gioco il concetto di cercapersone. Questo link indica che Paging is often done in Android. In realtà dispone solo di una piccola quantità di array in memoria e, a seconda delle necessità, continua a caricarlo nella memoria e a scaricare i dati precedenti dalla memoria se non lo si desidera.

Ad es. in qualsiasi tabella, in un colpo, l'utente può vedere al massimo 50 record, quindi dovrà scorrere (considerando che il suo schermo non ha le dimensioni di un iMax movie theatre). Quando scorre, carica il prossimo pezzo di dati e scarica tutti i dati che sono ora inattivi per l'utente.

+0

Purtroppo ho bisogno di tutti i 10000 (vedi domanda aggiornata). Quindi se ho il nome della classe da qualche parte nel mio codice attività, JVM caricherà la classe quando viene avviata la mia attività? – fhucho

+0

@fhucho - sì, lo farebbe. –

+0

Non sono sicuro di Android ma il sole JVM fa il lazy loading. La classe verrà inizializzata quando viene utilizzata per la prima volta. per esempio, la prima volta che alcuni codici usano effettivamente un valore statico della classe o invocano nuovi su di esso. La semplice importazione non fa nulla e se NEW o MyClass.staticMethod() non viene chiamato nel percorso di esecuzione, non viene mai caricato. –

1

Quando è caricato un tipo? Questa è una domanda sorprendentemente leggera alla risposta . Ciò è dovuto in gran parte a la notevole flessibilità offerta, dalla specifica JVM, alle implementazioni JVM . Il caricamento deve essere eseguito prima del collegamento e del collegamento deve essere eseguito prima dell'inizializzazione . Le specifiche VM stipulano i tempi di inizializzazione . Richiede rigorosamente lo che un tipo sia inizializzato sul suo primo utilizzo attivo (consultare l'Appendice A per un elenco di ciò che costituisce un "uso attivo "). Ciò significa che il caricamento (e il collegamento ) di un tipo DEVE essere eseguito in corrispondenza o prima del primo utilizzo attivo di tale tipo .

Da http://www.developer.com/java/other/article.php/2248831/Java-Class-Loading-The-Basics.htm

0

non credo che sarete felici con il mantenimento 10K stringhe, hardcoded al file Java.

Verificare se si utilizza il database corretto per il problema e se gli indici sono impostati correttamente. Un indice sbagliato può causare prestazioni davvero scadenti.

Inoltre, è necessario limitare la quantità di risultati restituiti dalla query, ma assicurarsi di non recuperare le voci una alla volta.

Se non ci sono problemi, è possibile precaricare le stringhe dal database all'avvio.

Si può pre-caricare, diciamo 10 voci, per ogni carattere. Se un personaggio è digitato, puoi precaricare le voci con quel personaggio che segue un altro e così via.

Problemi correlati