2010-07-21 13 views
21

Abbiamo un servizio che raccoglie continuamente i dati del sensore sul telefono. Questo servizio dovrebbe essere eseguito "per sempre", ad es. fino a quando l'utente vuole, e non essere ucciso dal sistema.Servizio Android ucciso con "non più desiderato" - come riavviarlo?

Per chiarimenti, questo servizio è non destinato a un'app da immettere sul mercato al pubblico, è stato scritto per uno studio scientifico. Quindi le persone che eseguono l'app sono pienamente consapevoli del fatto che la batteria si svuoterà più velocemente del solito, non è un problema.

In ogni caso, il mio problema è che il servizio viene ucciso dopo un po 'di corsa. A volte dopo un'ora, a volte solo dopo 7 o 10 ore.

Le voci di registro quando il servizio viene ucciso assomigliano a questo. Dice solo "non vuoi più", a volte senza nemmeno chiamare suDestroy(), per quanto posso dire.

07-20 17:07:11.593 I/ActivityManager( 85): No longer want my.project.datalogging (pid 23918): hidden #16 
07-20 17:07:11.593 I/WindowManager( 85): WIN DEATH: Window{44c61570 my.project.datalogging/my.project.datalogging.DataLoggingApp paused=false} 
07-20 17:07:11.603 I/BackgroundService(23925): onDestroy() 

o successivo (dopo ho riavviato manualmente):

07-20 19:00:49.677 I/ActivityManager( 85): No longer want my.project.datalogging:BackgroundService (pid 24421): hidden #17 
07-20 19:00:49.677 I/ActivityManager( 85): No longer want my.project.datalogging (pid 24415): hidden #18 
07-20 19:00:49.807 85 10707 I WindowManager: WIN DEATH: Window{44f1ea58 my.project.datalogging/my.project.datalogging.DataLoggingApp paused=false} 

vedo spesso altri servizi di essere uccisi con "vogliono più" e poi subito riavviato con "Scheduling riavvio del caduto servizio ". Per esempio qui con runkeeper:

07-20 17:30:45.503 I/ActivityManager( 85): No longer want com.fitnesskeeper.runkeeper (pid 24090): hidden #16 
07-20 17:30:45.603 W/ActivityManager( 85): Scheduling restart of crashed service com.fitnesskeeper.runkeeper/.services.RunKeeperService in 5000ms 
07-20 17:33:52.989 I/ActivityManager( 85): Start proc com.fitnesskeeper.runkeeper for service com.fitnesskeeper.runkeeper/.services.RunKeeperService: pid=24292 uid=10099 gids={3003, 1015} 

I registri non mostrano alcuna registrazione di memoria insufficiente. Il test viene eseguito su (diversi) Nexus One con 2.2 (Froyo FRF91).

C'è un modo per ottenere questo comportamento con la mia app? Riavvio automatico dopo essere stato ucciso?

O questo qualcosa di completamente diverso che sembra simile in logcat?

Se avete bisogno di ulteriori informazioni, basta chiedere e cercherò di fornire :-)

risposta

12

Come si avvia il servizio? Hai provato startForeground()? Questa non è una garanzia assoluta, ovviamente, ma dovrebbe almeno allungare la durata della vita.

+0

Grazie per la risposta. Non usiamo startForeground(), ma sembra una buona idea. L'ho implementato e attualmente sto testando per vedere se funziona. Questo può richiedere un po 'di tempo, dal momento che il servizio era già in grado di sopravvivere diverse ore senza essere ucciso. – pableu

+0

Non sono sicuro se esiste un modo standard di Android per garantire che il servizio rimanga attivo, mentre si lavora nello spazio Java (un servizio watchdog separato, pianificato per essere eseguito periodicamente e controllare che il servizio sia ancora attivo?). In caso contrario, potrebbe essere necessario andare nel livello NDK e Linux ... –

+0

Grazie per l'idea di startForeground(), il servizio è stato eseguito per quasi 24 ore su due telefoni separati e non è stato ucciso. Sembra fare il trucco :-) – pableu

6

Provare a sovrascrivere il metodo onCreate() del servizio. Se il servizio viene ucciso e quindi riavviato, viene chiamato onCreate(), ma non onStart(). Ad esempio, puoi aggiungere una chiamata a onStart() da onCreate per farlo comportarsi come RunKeeperService.

+2

Vota su. Assolutamente d'accordo che la soluzione dovrebbe essere quella di invocare un metodo di avvio all'interno di onCreate. Non sono d'accordo sulla chiamata all'avvio - non dovrebbe essere invocato direttamente. Basta invocare il proprio metodo per avviare in genere il servizio. –

+0

Solo una nota a margine, stavo avendo lo stesso problema. Sembra che onStart venga chiamato automaticamente. logcat mostra "Pianifica il riavvio del servizio in arresto ..." e dopo 5 secondi, il servizio riprende. Stesso comportamento in froyo e ICS/JB. – black

+1

Aggiungendo a quanto sopra, se onStartCommand restituisce START_STICKY, quindi Android chiamerà suCreate e suStartCommand. – black

Problemi correlati