Android Lollipop 5.0.1 SQLiteLog POSIX Errore 11 Errore SQLite: 3850

Sto riscontrando un problema durante l’aggiornamento di un’app per supportare Android Lollipop. L’app implementa un SyncAdapter che scrive su un db attraverso un fornitore di contenuti. Allo stesso tempo può succedere che l’utente stia navigando sul front-end dell’app dove i caricatori leggono gli stessi dati dal database. I caricatori ascoltano anche le modifiche ai dati.

Ora, se eseguo il programma su un dispositivo pre-Lollipop, tutto funziona senza errori.

Su Lollipop invece ricevo il seguente messaggio logcat:

11:20:59.344 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850 11:20:59.364 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850 11:20:59.364 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850 11:20:59.364 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850 

Ora, dai documenti SQLite:

(3850) SQLITE_IOERR_LOCK

Il codice di errore SQLITE_IOERR_LOCK è un codice di errore esteso per SQLITE_IOERR che indica un errore I / O nella logica di blocco del file consultivo. Solitamente un errore SQLITE_IOERR_LOCK indica un problema nell’ottenere un blocco PENDING. Tuttavia può anche indicare errori di blocco vari su alcuni VFS specializzati utilizzati su Mac. Tutto sembra funzionare correttamente ad un livello elevato (cioè vengono eseguite sia le letture che le scritture)

e:

Un blocco PENDING significa che il processo che blocca il blocco desidera scrivere sul database il prima ansible e attende solo che tutti i blocchi SHARED correnti vengano cancellati in modo che possa ottenere un blocco ESCLUSIVO. Non sono consentiti nuovi blocchi SHARED contro il database se è attivo un blocco PENDING, sebbene i blocchi SHARED esistenti possano continuare.

So che la versione di SQLite è stata aggiornata da alcune versioni principali di Lollipop, quindi sono incline a pensare che l’errore sia dovuto a qualche nuovo comportamento di SQLite che non riesco a isolare.

Tuttavia, tutto sembra funzionare bene da un punto di vista di livello superiore (l’App non si blocca, le letture e le scritture vengono eseguite, il framerate non cade, almeno per gli occhi umani), ma non vorrei ignorare il problema rilasciare l’app fino a quando non sono sicuro che non causerà problemi di corruzione dei dati.

Forse mi mancano alcune importanti modifiche al lollipop riguardanti i blocchi e l’accesso al database multiprocesso, ma ritengo che si tratti di un problema che si trova ad un livello inferiore rispetto al dominio Art / Dalvik e quindi deve essere corretto in un contesto NDK.

C’è un modo per risolvere questo problema senza distribuire una versione specifica dell’app di SQLite? C’è qualche opzione manifest / SQLite per evitare l’errore?

Grazie in anticipo

Writer blocca il database sia per la lettura che per la scrittura. Ciò significa che deve attendere che tutti i lettori finiscano e rilasciare i blocchi per ottenere il blocco.

Dopo che lo scrittore ha richiesto un blocco, i nuovi blocchi del lettore devono attendere che lo scrittore ottenga prima il lucchetto e poi lo rilasci.

Questa potrebbe essere una soluzione per te: la modalità WAL

Attivazione e configurazione della modalità WAL:

Per impostazione predefinita, una connessione al database SQLite riporta journal_mode = DELETE. Per convertire in modalità WAL, utilizzare il seguente pragma:

 PRAGMA journal_mode=WAL; 

WAL non bloccherà i lettori durante la scrittura, il che significa anche che lo scrittore non ha bisogno di attendere il rilascio dei blocchi di lettura correnti.

La versione minima di SQLite richiesta per WAL è 3.7.0 (2010-07-21) . Lollipop 5.0 utilizza SQLite 3.8.4.3, quindi WAL dovrebbe essere disponibile per te.

Ma WAL non esiste nella versione di Android meno di 3.0 anche se ci sono alcune eccezioni da questo. Dai un’occhiata alla versione di SQLite utilizzata in Android? . Se non hai bisogno che la tua app funzioni sotto Android 3.0, puoi utilizzare WAL.