Ho un frammento che ha un listview.ContentProvider chiama atomico? Risparmia onPause, carica in OnActivityCreated, dati vecchi
In onPause() Sto salvando la posizione di scorrimento Y della listview in ContentProvider.
Lo stesso frammento su onResume o onActivityCreated utilizza un caricatore per afferrare la posizione di scorrimento y dal contentprovider e ripristinare la posizione di scorrimento.
Se esco dall'attività/frammento e ci ritorno, funziona, la listview ritorna all'ultima posizione aperta da quando è stata salvata sul contentprovider in onPause. Quindi il codice è corretto al 100%.
Cosa non va bene, sono i dati su una rotazione. onPause salva bene, ma il carico dopo onCreateActivity risulta nel recuperare i vecchi dati, i dati prima del salvataggio in onPause. Ne consegue che il listview ritorna alla posizione OLD quando apriva per la prima volta l'app e non la posizione in cui il listview era precedente alla rotazione.
Sembra una condizione di gara evidente che il salvataggio nel provider di contenuti durante onPause non è completato in onPause, con conseguente caricamento di vecchi dati dopo la rotazione.
Quindi una rotazione sul mio telefono si presenta come questo
01:31:33.026: ThreadViewerFragment.java(235):onPause Saved(position:Yposition): 59:-74
01:31:33.256: ThreadViewerFragment.java(194):onActivityCreated
01:31:33.266: ThreadViewerFragment.java(309):onLoadFinished Load(position:Yposition): 62:-149 //initial load is of old values
01:31:33.266: ThreadViewerFragment.java(309):onLoadFinished Load(position:Yposition): 62:-149
01:31:33.596: ThreadViewerFragment.java(309):onLoadFinished Load(position:Yposition): 59:-74 //this is loaded due to notification by the save in onPause which is supposed to be finished before recreating the new fragment???
Così l'ordine guarda bene (non sembra una condizione di competizione in termini di attività/flusso frammento), ma i vecchi valori chiaramente, è caricato invece dei valori appena salvati di 59: -74.
Non mi occupo di un lavoro, so come usare saveInstanceState ecc. Ma perché dovrei raddoppiare il mio codice, c'è un modo per forzare il contentprovider a comportarsi atomicamente (cosa che pensavo che fosse già?)
Modifica: aggiunta di codice e perfezionata la domanda un po 'meglio perché non sono ancora soddisfatto che siamo più vicini a capire se contentprovider chiama il blocco mentre viene eseguito e/o se quelle chiamate sono atomiche o se è solo un fraintendimento di contentproviders e caricatori.
In onPause, mi risparmio fuori la posizione Y della scheda di prodotto
@Override
public void onPause() {
super.onPause();
Utils.logv("onPause Saved position: " + mLastRead + ", " + mYPos);
ContentValues contentValues = new ContentValues();
contentValues.put(ProductsContract.Products.Y_POS, mYpos);
int updateCount = getActivity().getContentResolver().update(
Uri.parse(ProductsContract.Products.CONTENT_URI + "/" + mId),
contentValues, null, null);
}
mio capire è che la chiamata di aggiornamento deve essere una chiamata di blocco, e si verifica prima che il frammento viene distrutta e prima il nuovo frammento è stato creato per gestire la rotazione
in sul curriculum I fuoco il mio caricatore
public void onResume() {
super.onResume();
getLoaderManager().initLoader(PRODUCTS_LOADER_ID, null, this);
}
E nel mio caricatore ottengo il cursore, che ha in modo affidabile i vecchi dati dopo una rotazione, ma va bene in qualsiasi altra circostanza
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
if(cursor.moveToFirst()){
mYpos = cursor.getInt(cursor.getColumnIndex(ProductsContract.Products.Y_POS));
Utils.logv("loader: " + mYpos);
}
}
Così ribadire, dopo una rotazione, il caricatore fornirà in modo coerente vecchi dati.
Sto pensando che forse il caricatore è obsoleto e non il content provider stesso? Che il cursore viene salvato e ripristinato dopo la rotazione anche se è stantio?
È certamente il caso con l'app di esempio SDK 8 NotePad su Android 2.3. Imposta un punto di interruzione in onResume() (alla riga o prima della riga "mText.setTextKeepState (nota);"), apporta le modifiche a una nota, attiva la schermata, sblocca lo schermo e il testo della nota continua a fare le modifiche quando lo screenlock è stato attivato. Passa su onResume() e dopo aver eseguito "String note = mCursor.getString (COLUMN_INDEX_NOTE);" dovresti trovare il testo della nota originale ripristinato. – Huperniketes