JavascriptProva

giovedì 16 giugno 2016

Chiusura di AlarmManager, onsiderazioni sul ciclo di vita di un Service, chiusura corretta di TTS.

Sarebbe il caso di vedere come si può terminare un AlarmManager.
Forse anche qui c'è un problema analogo a quallo del binding...

Ecco, ho trovato, ma ho problemi di TTS.
Ottengo un messaggio di errore in cui viene segnalato un problema relativo al TTS.
Il TextToSpeech andrebbe chiuso. Ma coms?
Ecco. Scopro che TextToSpeech ha due metodi: stop() e shutdown()
Il problema è: se io ho avviato un service da MainActivity, il codice del TTS è sul Service, non sulla main. Come faccio a chiudere TTS?
La cosa migliore è chiudere non appena TTS ha cessato di parlare.
Solo voglio vedere che differenza c'è fra stop e shutdown.

Ma che scemo! Faccio eseguire un metodo del Service che chiami i metodi del TTS prima di stoppare il Service.
Il metodo stop() interrompe la frase corrente, mentre shutdown() rilascia proprio le risorse per il tts.

Se voglio che il Service si stoppi proprio una volta che la frase è stata detta, mi conviene dunque prima stoppare il tts e poi stoppare il Service.

Vorrei verificare il messaggio di errore che ho ottenuto stoppando il Service mediante la pressione del pulsante.
Il codidce è questo:
  button.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    if(alarmManager!=null) {
     alarmManager.cancel(pendingIntent);
     stopService(new Intent(getApplicationContext(),Servizio.class));
     
    }
    
   }
  });
Il codice del bottone stoppa alarmManager e poi stoppa il Service.
Faccio partire il programma, che dopo 3 minuti dovrebbe dirmi una @Override public void onDestroy(){ super.onDestroy(); Log.e("Servizio","distrutto"); }.
Se schiaccio il pulsante prima che venga detta la frase, ottengo il messaggio di errore relativo al tts.
Probabilmente perché devo prima chiudere il tts, prima che sia chiuso il Service.

Vediamo se stoppare il service equivale a Destroy.
Ho iniziato aggiungendo al Service questo metodo:
 @Override
 public void onDestroy(){
  super.onDestroy();
  Log.e("Servizio","distrutto");
 }
Quando si stoppa il Service da esterno o lo si fa stoppare dall'interno, dunque, il service si autodistrugge.
Mi discosto un po' dal discorso iniziale del tts e sperimento un po' sul ciclo di vita di un service.
Pongo degli indicatori in onCreate e onDestroy.
 @Override
 public void onCreate(){
  super.onCreate();
  Log.d("onCreate","Creazione");
 @Override
 public int onStartCommand(Intent intent, int flags, int startUI){
  Log.e("onStartCommand","start");
  tts.speak("Buongiorno, bello", TextToSpeech.QUEUE_FLUSH,null);
  
  return Service.START_STICKY;
 @Override
 public void onDestroy(){
  super.onDestroy();
  Log.e("onDestroy","distruzione");
 }
Vediamo un po' i "marker" come si comportano quando chiamo un service e poi lo distruggo. Sempre con quel codice nel bottone di "distruzione", quindi non so se sia affidabile... Proviamo, comunque!
06-16 13:59:08.230: E/onCreate(15611): Creazione
06-16 13:59:08.240: W/ApplicationPackageManager(15611): getCSCPackageItemText()
06-16 13:59:08.321: I/TextToSpeech(15611): Sucessfully bound to com.google.android.tts
06-16 13:59:08.321: E/onStartCommand(15611): start
06-16 13:59:08.321: W/TextToSpeech(15611): speak failed: not bound to TTS engine
06-16 13:59:08.411: D/OpenGLRenderer(15611): Enabling debug mode 0
06-16 13:59:08.491: I/Timeline(15611): Timeline: Activity_idle id: android.os.BinderProxy@41eaa110 time:36195801
06-16 13:59:11.123: I/TextToSpeech(15611): Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
06-16 13:59:11.133: I/TextToSpeech(15611): Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
06-16 13:59:13.105: E/onStartCommand(15611): start
06-16 13:59:33.425: E/onDestroy(15611): distruzione
06-16 13:59:33.525: E/ActivityThread(15611): Service com.example.esercizio6.Servizio has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@41ed2638 that was originally bound here
Provato! Quando il Service viene avviato, entrano onCreate e onStartCommand. Quindi alla pressione del pulsante entra in gioco onDestroy.
Però dopo quest'ultimo ottengo un errore di TTS.

Il codice cancella AlarmManager e distrugge il Service, e penso che probabilmente l'errore sia dovuto al fatto che non viene debitamente chiuso TTS.
Vi aggiungo il comando tts.stop():
 @Override
 public void onDestroy(){
  super.onDestroy();
  Log.e("onDestroy","distruzione");
  tts.stop();
 }
Ecco:
06-16 14:04:33.708: E/onStartCommand(27773): start
06-16 14:04:44.428: E/onDestroy(27773): distruzione
06-16 14:04:44.498: E/ActivityThread(27773): Service com.example.esercizio6.Servizio has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@41ecf3c8 that was originally bound here
06-16 14:04:44.498: E/ActivityThread(27773): android.app.ServiceConnectionLeaked: Service com.example.esercizio6.Servizio has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@41ecf3c8 that was originally bound here


VI aggiungo il comando tts.shutdown():
 @Override
 public void onDestroy(){
  super.onDestroy();
  Log.e("onDestroy","distruzione");
  tts.stop();
  tts.shutdown();
 }
06-16 14:07:20.230: E/onStartCommand(16713): start
06-16 14:07:26.907: E/onDestroy(16713): distruzione
Okay!
Quindi, nel momento in cui si chiude un Service (ma anche un'Activity, meglio ricordarlo) si deve stoppare e poi fare shutdown sul tts.

Nessun commento:

Posta un commento