Se distruggo tutti e due nello stesso tempo cosa accads?
MainActivity:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(new Intent(getApplicationContext(),Alfa.class)); stopService(new Intent(getApplicationContext(),Beta.class)); } });Non funziona. Ho sempre quel succedersi indiavolato di giri viziosi fra l'uno e l'altro Service.
Ho risolto in questo modo: ho una variabile globale booleana chiamata stop dichiarata in una classe chiamata Globals:
public class Globals { public static boolean stop=false; }e pongo la condizione a ognuno dei due Services, per chiamare l'altro, che la variabile sia false:
Alfa:
public class Alfa extends Service{
@Override
public int onStartCommand(Intent intent, int flags, int startUI){
Log.v("ALFA","ONSTARTCOMMAND");
stopSelf();
Log.v("ALFA","/ ONSTARTCOMMAND");
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy(){
Log.v("ALFA","ONDESTROY");
if(Globals.stop==false)startService(new Intent(this,Beta.class));
Log.v("ALFA","/ ONDESTROY");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Beta:
public class Beta extends Service{
@Override
public int onStartCommand(Intent intent, int flags, int startUI){
Log.v("BETA","ONSTARTCOMMAND");
Log.e("BETA","Esecuzione del compito stabilito");
stopSelf();
Log.v("BETA","/ ONSTARTCOMMAND");
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy(){
Log.v("BETA","ONDESTROY");
if(Globals.stop==false)startService(new Intent(this,Alfa.class));
Log.v("BETA","/ ONDESTROY");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Così facendo, pare funzioni egregiamente, ponendo che in MainActivity il pulsante "Stop" dia alla variabile il valore true
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Globals.stop=true; Log.d("STOP","TRUE"); } });...ovviamente, facendo in modo che il pulsante Start reimposti la variabile a false:
bttStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Globals.stop=false; intent=new Intent(getApplicationContext(),Alfa.class); startService(intent); } });E cavoli, funziona!
Metto un "marker" che mi dia il valore della variabile nel momento in cui viene impostata a true e mi analizzo un po' la cosa in LogCat:
06-20 18:57:45.648: V/ALFA(1873): ONDESTROY 06-20 18:57:45.658: V/ALFA(1873): / ONDESTROY 06-20 18:57:45.658: V/BETA(1873): ONSTARTCOMMAND 06-20 18:57:45.658: E/BETA(1873): Esecuzione del compito stabilito 06-20 18:57:45.658: V/BETA(1873): / ONSTARTCOMMAND 06-20 18:57:45.658: D/STOP(1873): TRUE 06-20 18:57:45.658: V/BETA(1873): ONDESTROY 06-20 18:57:45.658: V/BETA(1873): / ONDESTROYQui la variabile è stata impostata a TRUE dopo che Beta ha eseguito onStartCommand e ha chiamato onDestroy: arrivato a onDestroy il codice trova la variabile TRUE e non chiama Alfa, così il ciclo si interrompe.
06-20 19:00:08.708: V/BETA(1873): / ONSTARTCOMMAND 06-20 19:00:08.708: V/BETA(1873): ONDESTROY 06-20 19:00:08.718: V/BETA(1873): / ONDESTROY 06-20 19:00:08.718: V/ALFA(1873): ONSTARTCOMMAND 06-20 19:00:08.718: V/ALFA(1873): / ONSTARTCOMMAND 06-20 19:00:08.718: D/STOP(1873): TRUE 06-20 19:00:08.728: V/ALFA(1873): ONDESTROY 06-20 19:00:08.728: V/ALFA(1873): / ONDESTROYAlfa ha eseguito onStartCommand chiamando onDestroy, ma nel frattempo la variabile globale è diventata TRUE, e così il codice di onDestroy non chiama più Beta e il ciclo si interrompe.
06-20 19:01:24.222: V/ALFA(1873): ONDESTROY 06-20 19:01:24.222: V/ALFA(1873): / ONDESTROY 06-20 19:01:24.232: D/STOP(1873): TRUE 06-20 19:01:24.232: V/BETA(1873): ONSTARTCOMMAND 06-20 19:01:24.232: E/BETA(1873): Esecuzione del compito stabilito 06-20 19:01:24.232: V/BETA(1873): / ONSTARTCOMMAND 06-20 19:01:24.242: V/BETA(1873): ONDESTROY 06-20 19:01:24.242: V/BETA(1873): / ONDESTROYEcco, questa è più interessante: Alfa ha appena chiamato Beta, e nel frattempo la variabile diventa TRUE: dato che la chiamata è già partita, il compito viene comunque eseguito, quindi si va a onDestroy e Beta non chiama più Alfa dato che incontra un TRUE.
Se io voglio interrompere l'esecuzione del programma nel preciso momento in cui schiaccio il pulsante Stop, ossia nel preciso momento in cui la variabile diventa TRUE, questo non va più bene. In tempi rapidi, la differenza non si nota, ma se io devo inserire un Timer in modo da far diventare questi tempi minuti od ore, allora il problema emerge, perché potrei avere la cessazione dell'attività del programma anche molte ore dopo averlo interrotto con il pulsante Stop
Studiamo una soluzione...
Non mi piace molto perché mi sembrerebbe più elegante una soluzione con una sola verifica di Globals.stop, ma dovrebbe funzionare:
Beta:
public int onStartCommand(Intent intent, int flags, int startUI){
Log.v("BETA","ONSTARTCOMMAND");
if(Globals.stop==false)Log.e("BETA","Esecuzione del compito stabilito");
stopSelf();
Log.v("BETA","/ ONSTARTCOMMAND");
return Service.START_NOT_STICKY;
}
Ecco, dopo vari tentativi, TRUE è ricapitato nel posto che mi interessa analizzare:
06-20 19:10:09.614: V/ALFA(5123): ONSTARTCOMMAND 06-20 19:10:09.614: V/ALFA(5123): / ONSTARTCOMMAND 06-20 19:10:09.614: V/ALFA(5123): ONDESTROY 06-20 19:10:09.624: V/ALFA(5123): / ONDESTROY 06-20 19:10:09.654: D/STOP(5123): TRUE 06-20 19:10:09.654: D/dalvikvm(5123): GC_EXPLICIT freed 501K, 47% free 6875K/12928K, paused 2ms+4ms, total 32ms 06-20 19:10:09.674: V/BETA(5123): ONSTARTCOMMAND 06-20 19:10:09.674: V/BETA(5123): / ONSTARTCOMMAND 06-20 19:10:09.674: V/BETA(5123): ONDESTROY 06-20 19:10:09.674: V/BETA(5123): / ONDESTROYCosì facendo, viene eseguito ONSTARTCOMMAND ma senza che venga eseguito il compito specifico.
Compare quel codice che non riesco a capire...
06-20 19:12:37.989: V/ALFA(5123): ONDESTROY 06-20 19:12:37.999: V/ALFA(5123): / ONDESTROY 06-20 19:12:37.999: D/STOP(5123): TRUE 06-20 19:12:37.999: V/BETA(5123): ONSTARTCOMMAND 06-20 19:12:37.999: V/BETA(5123): / ONSTARTCOMMAND 06-20 19:12:38.009: V/BETA(5123): ONDESTROY 06-20 19:12:38.009: V/BETA(5123): / ONDESTROYAdesso è ricapitato nello stesso punto, ma non appare nulla... Non so. Forse sarò in condizione di capirlo in tempi futuri...
Comunque, questo sistema FUNZIONA!
Nessun commento:
Posta un commento