2010-10-18 11 views
14

Ho letto la documentazione di Android e mi chiedo se qualcuno possa far luce su cosa succede a un'istanza di servizio quando un servizio avviato con START_STICKY ha eliminato il processo. Suppongo che anche i dati dello stato locale (variabili di istanza) vadano persi. Android fa qualcosa per aiutare a popolare lo stato locale quando ricrea il servizio?onStartCommand dopo che il processo di servizio è terminato quando è iniziato con START_STICKY

Ho avuto alcuni dati che sono stati inviati al servizio in un intento. In onStateCommand(), popolerei i dati dell'istanza del servizio in base a ciò che era nell'intento. Da quanto ho letto nei documenti Android, l'intento trasmesso a onStartCommand() sarà nullo quando il servizio è stato ucciso e riavviato (con START_STICKY). Significa che perdo il mio intento e i dati dei membri del servizio quando viene ricreato il servizio?

risposta

16

Quando un processo viene ucciso e ricreato, ripercorre l'intero ciclo di vita (a partire da onCreate). A seconda di come è stato ucciso e di come si salvano i dati potrebbe essere o non essere disponibile per voi.

Per riprendere l'intento, c'è una bandiera per START_REDELIVER_INTENT che riconsegna l'intento.

+0

Grazie per aver confermato i miei sospetti. Non sapevo di START_REDLIVER_INTENT (deve aver sorvolato quella parte dei documenti). – adstro

+0

Grazie amico, sono stato licenziato da questo bug per quasi un mese ... Finalmente scoperto Android OS ha ucciso il servizio ... –

+0

Nice. Non ho mai saputo di 'START_REDELIVER_INTENT', sicuramente è stato utile @Falmarri –

1

Android non ripopola i valori dei dati "persi" quando riavvia il servizio, quindi il codice deve soddisfare questa eventualità.

Il mio approccio è utilizzare tutte le variabili di stato non primitive e lasciarle come null. In questo modo posso verificare null e adottare le misure appropriate per inizializzarli come e quando.

Ho preso a memorizzare dati leggeri che voglio persistere attraverso riavvii delle applicazioni nelle preferenze dell'applicazione.

2

Recentemente mi sono imbattuto in questo stesso problema. Il servizio non fornisce strumenti incorporati per il salvataggio dello stato e l'ultimo tentativo potrebbe non essere sufficiente per riportare il servizio allo stato precedente. La mia soluzione era di mantenere lo stato di attività e passare tale stato al servizio tramite startService(). Il servizio poi basta genera gli eventi presso l'attività, come:

  • Ecco un aggiornamento
  • qualcosa di morto e qui è l'eccezione
  • ho ucciso, vi prego di ripartire con qualsiasi stato necessario

Questo approccio ha ripulito molto il mio progetto, e sia il servizio che l'attività sono resilienti all'essere uccisi.

+2

Puoi condividere qualche pezzo di codice per lo stesso .. ?? Il concetto sembra ideale, ma non è possibile implementarlo –

1

utilizzare la memoria interna per il salvataggio dell'oggetto o il suo campo singolarmente.

public void writeToInternalStorage(String fileName,String userName) 
    { 
     try{ 
      String endOfLine = System.getProperty("line.separator"); 
      StringBuffer buffer = new StringBuffer(); 

      FileOutputStream fos = openFileOutput(fileName, Context.MODE_PRIVATE); //// MODE_PRIVATE will create the file (or replace a file of the same name) and make it private to your application. Other modes available are: MODE_APPEND, MODE_WORLD_READABLE, and MODE_WORLD_WRITEABLE. 

      buffer.append(userName.toString() + endOfLine); 
      fos.write(buffer.toString().getBytes()); 


      Log.v(TAG, "writeFileToInternalStorage complete.. " + buffer.toString()); 
      //  writer.write(userName); 

      fos.close(); 
     } 
     catch(Exception e) 
     { 
      Log.v(TAG, "Error: " + e.getMessage()); 
      ExceptionNotificationMessage("writeToInternalStorage() Error: " + e.getMessage()); 
     } 
    } 

    public String readFromInternalStorage(String fileName) 
    { 
     try{ 
      File file = this.getFileStreamPath(fileName); 
      if(file.exists() == true) 
      { 
       Log.v(TAG, "readFileFromInternalStorage File found...");  

       FileInputStream fis = openFileInput(fileName); 
       StringBuilder buffer = new StringBuilder();    
       int ch; 
       while((ch = fis.read()) != -1){ 
        buffer.append((char)ch); 
       } 

       Log.v(TAG, "readFileFromInternalStorage complete.. " + buffer.toString()); 
       fis.close(); 

       return buffer.toString(); 
      } 
     } 
     catch(Exception e) 
     { 
      Log.v(TAG, "Error: " + e.getMessage()); 
      ExceptionNotificationMessage("readFromInternalStorage() Error: " + e.getMessage()); 
     } 
     return ""; 
    } 
Problemi correlati