2010-11-17 16 views
102

Sto lavorando a un'applicazione Android abbastanza complessa che richiede una grande quantità di dati sull'applicazione (direi un totale di circa 500 KB - è così grande per un dispositivo mobile dispositivo?). Da quello che posso dire, qualsiasi cambiamento di orientamento nell'applicazione (nell'attività, per essere più precisi) provoca una completa distruzione e ricreazione dell'attività. Sulla base dei miei risultati, la classe Application non ha lo stesso ciclo di vita (vale a dire, a tutti gli effetti, sempre istanziata). Ha senso memorizzare le informazioni di stato all'interno della classe dell'applicazione e quindi fare riferimento ad essa dall'attività, oppure non è generalmente il metodo "accettabile" a causa dei vincoli di memoria sui dispositivi mobili? Apprezzo davvero qualche consiglio su questo argomento. Grazie!Utilizzo della classe Applicazione Android per mantenere i dati

+8

Tieni presente che i dati nella tua applicazione possono ancora essere eliminati se la tua app viene messa in background, quindi questa non è una soluzione ai dati persistenti che vuoi sempre riuscire a recuperare. Serve semplicemente come metodo per non dover ricreare spesso oggetti costosi. –

+2

Mayra; Non penso che l'app sia "di solito" cancellata (sebbene, come qualcuno più avanti in questa discussione, "possa" essere). Probabilmente andrò con qualche tipo di approccio "ibrido" all'uso dell'applicazione per archiviare e caricare i dati, ma poi usare l'attributo "android: orientation" sull'attività nel file manifest per sovrascrivere il normale comportamento di abbattere e ricostruire l'attività. Tutto ciò, ovviamente, presuppone che l'applicazione possa determinare "quando" viene distrutto in modo che i dati possano essere mantenuti. – Dave

risposta

129

Non penso che 500kb sarà un grosso problema.

Quello che hai descritto è esattamente come ho affrontato il mio problema di perdere dati in un'attività. Ho creato un singleton globale nella classe Application e sono riuscito ad accedervi dalle attività che ho usato.

È possibile passare i dati in un Global Singleton se verrà utilizzato molto.

public class YourApplication extends Application 
{  
    public SomeDataClass data = new SomeDataClass(); 
} 

Poi chiamare in qualsiasi attività da:

YourApplication appState = ((YourApplication)this.getApplication()); 
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here. 

discuto che here in my blog post, sotto la sezione "Global Singleton."

+1

Purtroppo il post del blog in questione non è più disponibile a quell'indirizzo. – mikebabcock

+1

Ho spostato le cose sul mio sito. Fino a quando non viene corretto, puoi trovarlo su archive.org qui: https://web.archive.org/web/20130818035631/http://www.bryandenny.com/index.php/2010/05/25/what- i-learn-from-writing-my-first-android-application –

+1

so che questo è un vecchio post ma ho appena trovato un problema che questo potrebbe risolvere, tuttavia questa classe ha bisogno di essere declamata nel manifest in qualche modo, no? Non riesco ad accettare la lezione, quindi sentiti come questo è quello che mi manca ... –

1

È possibile ignorare la funzionalità di orientamento per assicurarsi che l'attività non venga distrutta e ricreata. Guarda here.

+15

Puoi fare un sacco di cose. Non significa che siano buone idee. Questa non è una buona idea. – Andrew

+0

Il test modificando l'orientamento dello schermo è il modo più semplice per assicurarsi che l'app esegua ciò che Android presuppone che faccia. – 18446744073709551615

55

Quelli che contano sull'istanza Application sono errati. In un primo momento, può sembrare che lo Application esista finché dura l'intera procedura dell'app, ma questa è un'ipotesi errata.

Il sistema operativo può interrompere i processi se necessario. Tutti i processi sono suddivisi in 5 livelli di "killability" specified in the doc.

Così, ad esempio, se la tua app passa in secondo piano a causa della risposta dell'utente a una chiamata in arrivo, a seconda dello stato della RAM, il sistema operativo può (o non può) uccidere il processo (distruggendo lo Application istanza nel processo).

Penso che un approccio migliore sarebbe quello di persist your data to internal storage file e quindi leggerlo quando l'attività riprenderà.

UPDATE:

ho ricevuto molti feedback negativi, quindi è il momento di aggiungere una precisazione. :) Beh, inizialmente ho usato un presupposto errato che lo stato sia davvero importante per l'app. Tuttavia, se la tua app è a posto che a volte lo stato è perso (potrebbero essere alcune immagini che saranno solo rilette/ridistribuite), allora è completamente OK mantenerlo come membro di Application.

+13

Se l'applicazione viene uccisa, allora a chi importa, giusto? L'applicazione è sparita. A quanto ho capito, Android recupererà i processi che contengono memoria come Attività. Se il processo che contiene l'applicazione viene ucciso (se Android lo farà anche?), È essenzialmente come uccidere l'app. L'utente dovrà avviare nuovamente l'app e, a quel punto, a chi importa? È una nuova istanza dell'applicazione. – Andrew

+13

Questa è stata una sorpresa per noi in produzione. Credetemi Android uccide i processi, dipende solo dallo stato della RAM e da altri fattori descritti nella documentazione. È stato un incubo per noi, quindi ho solo condiviso la mia vera esperienza.Beh, non avevamo questo sugli emulatori, ma nel mondo reale alcuni dispositivi sono "sovraccarichi" di app, quindi uccidere un processo in background è una situazione normale. Sì, se l'utente decide di mettere l'app in primo piano - il sistema operativo ripristina il suo stack includendo l'istanza di 'Applicazione', tuttavia non ci saranno dati statici su cui conti a meno che tu non lo abbia persistito. –

+2

Penso che probabilmente userò un approccio ibrido. Sapevo già del trucco manifest per ignorare il cambiamento di orientamento (che ha altri vantaggi). Dal momento che l'applicazione è un gioco, non sono sicuro che la persistenza dei dati tra i lanci sia abbastanza "importante"; anche se probabilmente non sarebbe terribilmente difficile dato che la maggior parte dei dati può essere serializzata (anche se non vorrei serializzare e non serializzare tra ogni cambiamento di orientamento). Apprezzo decisamente l'input. Non direi che quelli che dipendono dall'istanza dell'app sono "sbagliati". Molto dipende dall'app :). – Dave

6

Se si desidera accedere a "Global Singleton" al di fuori di un'attività e non si desidera passare lo Context attraverso tutti gli oggetti coinvolti per ottenere il singleton, è possibile semplicemente definire un attributo statico nella classe dell'applicazione, che detiene il riferimento a se stesso. Basta inizializzare l'attributo nel metodo onCreate().

Ad esempio:

public class ApplicationController extends Application { 
    private static ApplicationController _appCtrl; 

    public static ApplicationController getAppCtrl() 
    { 
     return _appCtrl; 
    } 
} 

Perché sottoclassi di Application è inoltre possibile ottenere le risorse, si potrebbe accedervi semplicemente quando si definisce un metodo statico, che li restituisce, come:

public static Resources getAppResources() 
{ 
    return _appCtrl.getResources(); 
} 

Ma fare molta attenzione quando si fa il giro dei riferimenti di contesto a avoid memory leaks.

+6

Hai dimenticato di notare che devi aggiungere android: name = ". ApplicationController" xml attribuisci il tag dell'applicazione nel tuo manifest per la classe da istanziare. – eggie5

+0

In realtà non è necessario estendere 'Applicazione' per fare ciò. Puoi dichiarare una variabile membro statica in ** qualsiasi classe ** per fare ciò. –

2

Dave, che tipo di dati è? Se si tratta di dati generali che riguardano l'applicazione nel suo insieme (esempio: dati utente), quindi estendere la classe dell'applicazione e memorizzarla lì. Se i dati appartengono all'attività, è necessario utilizzare i gestori onSaveInstanceState e onRestoreInstanceState per mantenere i dati sulla rotazione dello schermo.

0

È possibile creare classe di applicazione e salvare tutti i dati su quel calss per utilizzarlo in qualsiasi punto dell'applicazione.

Problemi correlati