2011-09-19 13 views
8

Sto lavorando sulla mia prima applicazione Android. Ha un modello che viene mantenuto in un database mentre l'utente effettua gli aggiornamenti.onSaveInstanceState/onPause - attendere che lo stato è completamente salvato prima di processo che permette di essere ucciso

Quando viene chiamato onSaveInsanceState, voglio salvare un ID che può essere utilizzato per caricare il documento su cui l'utente stava lavorando dal database. Ma questo può accadere solo quando il documento ha colpito completamente il database. In alcuni casi, persistendo un documento complesso può richiedere diversi secondi (Spero che questo potrà accelerare una volta mi prendo tutta la registrazione dettagliata, e in uso effettivo di un documento complesso sarà costruito dall'utente in più fasi, ognuna delle quali sarà mantenuto nel database, quindi non è molto probabile che tutti i documenti complessi vengano salvati tutti in una volta sola).

Ora, la regola # 1 di filettatura su Android è "non bloccare il thread UI", così naturalmente interazioni DB avvengono su un thread separato. Ma la mia comprensione del ciclo di vita di Android è che in molti casi viene chiamato onSaveInstanceState perché il sistema Android vuole uccidere il processo. Ciò suggerisce che non posso permettere a questo metodo di tornare finché il thread DB non termina il salvataggio del documento (e in effetti con il mio progetto attuale, non so in realtà quale sia il numero id del documento fino a quando non è stato salvato nel DB, quindi non posso nemmeno metterlo nel bundle di stato salvato).

È opportuno in queste circostanze per bloccare il thread dell'interfaccia utente in attesa che il compito persistono da fare? Quando viene chiamato il numero onSaveInstanceState perché il processo viene eliminato, l'app non è più visibile in primo piano, quindi non c'è alcuna interfaccia per non rispondere.

Ma onSaveInstanceState viene chiamato anche quando l'istanza di attività viene eliminata da un aggiornamento di configurazione, che si verifica quando l'orientamento dello schermo cambia. È molto spiacevole quando ruotare lo schermo di lato non riesce a fare nulla per diversi secondi. In questo caso il processo (e quindi lo spazio di memoria) è ancora in giro, quindi non ho strettamente bisogno di assicurare che il documento colpisca il database, se posso semplicemente memorizzare un riferimento ad esso nel pacchetto invece del suo id. Ma non sono a conoscenza di un modo per dire la differenza tra questi due casi.

Esiste una pratica accettata per queste situazioni? Devo solo bloccare il filo per essere sicuro? Posso semplicemente usare normali primitive di thread Java per bloccare e attendere? C'è qualcosa che posso fare che non significa bloccare il thread, ma compito sarà finito prima di Android chiude il processo assicura il persistere?

Tutto ciò vale anche per , in quanto onSaveInstanceState non verrà necessariamente chiamato.

risposta

0

Dovresti provare AsyncTask, che bloccherà il tuo ui ma non mostrerà lo schermo vuoto, caricherà gli elementi xml necessari e poi richiamerà l'attività Async, in un'attività asincrona salva il tuo documento nel database.

segui questo link: AyncTask Exmaple

+0

Ho pensato che il punto di 'AsyncTask' era che * non * blocca il thread dell'interfaccia utente? Non è questo il senso di usarlo per fare operazioni di lunga durata? – Ben

+0

Se hai problemi con le modifiche di Config, non preoccuparti, scrivi i configChanges nel file mainfest in questo tag attività, quindi non inviterà mai onSaveInstanceState() quando l'orientamento viene modificato. Non forza l'attività per riavviare –

+0

Questo è utile (ma ha i suoi problemi), ma è completamente irrilevante alla domanda, ovvero come faccio a garantire che i dati persistenti effettivamente salvati quando l'app viene uccisa se il salvataggio è fatto da uno sfondo filo. – Ben

2

Non devi fare per il salvataggio persistente onSaveInstanceState, si può praticamente solo salvare lo stato esempio nel Bundle in modo che l'istanza può essere rapidamente ripreso in onRestoreInstanceState.

La documentazione che si dovrebbe scrivere dati persistenti cruciali (come ad esempio le modifiche utente) per lo stoccaggio in , ma afferma anche che dovrebbe essere veloce in modo che l'attività successiva può iniziare a fare qualunque cosa sia che vuole fare.

Penso che la mia raccomandazione qui sarebbe quella di salvare il testo del documento e qualsiasi cosa nel pacchetto in onSaveInstanceState e ripristinarlo in onRestoreInstanceState. Utilizzare per salvare una "copia di backup" da qualche parte velocemente (file temporaneo forse?) Che può quindi essere ripristinata in onResume se non è stata salvata nel database. E utilizzare onStop (che viene chiamato quando l'attività è già in background) per salvare effettivamente i dati nel database.

Nota che l'attività potrebbe avere ucciso dopo è stato chiamato (mai prima d'ora, a meno che il sistema ha molto molto poche risorse a sinistra ...), è per questo che vorrei salvare un backup rapido prima di provare a impegnarsi nel database .

Edit - Extra sulla base dei commenti

Per assicurarsi che il thread in background che sta facendo il processo di salvataggio è fatto il salvataggio prima che la domanda può essere ucciso dal sistema, penso va bene per bloccare e aspettare per il thread di salvataggio da completare prima di tornare da ma si consiglia di utilizzare android:configChanges="orientation" per impedire il riavvio delle attività (e la chiamata) quando l'orientamento cambia.

+0

Realizzo tutto nel database non appena viene scritto. Non lo faccio in 'onSaveInstanceState'. Il problema è che l'ultima operazione di salvataggio innescata * potrebbe essere ancora in corso * quando viene chiamato 'onSaveInstanceState'. Devo sapere come aspettare per dire al sistema Android "va bene uccidermi ora" finché i dati persistenti non sono effettivamente al sicuro. Se il sistema è così basso sulle risorse che uccide arbitrariamente il mio processo, va bene perdere le modifiche non monitorate, ma non voglio che il processo venga ucciso a metà di un'operazione DB in condizioni operative normali. – Ben

+0

In tal caso, puoi saltare "onSaveInstanceState' usando android: configChanges =" orientation "nel file manifest come suggerito da mak_just4anything. Assicurati che il salvataggio sia fatto in 'onPause' /' onStop'. Maggiori informazioni qui: http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange – Zharf

+0

Ovviamente non sto facendo capire la mia domanda. Diciamo che il mio 'onPause' chiama' tellBackgroundThreadToSaveStateToDb'. Buona. Fatto. Ora, come faccio a garantire che il thread in background non stia ancora elaborando tale richiesta quando Android vuole interrompere il mio processo? – Ben

Problemi correlati