Autore Topic: servizi "zombie"...  (Letto 1154 volte)

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
servizi "zombie"...
« il: 16 Novembre 2010, 12:53:47 CET »
0
Salve a tutti!
Ecco un mio nuovo problema!

Ho un'Activity, dalla quale faccio partire 3 Service.
Ciascuno di questi all'interno della sua onCreate(), realizza un Thread che mi serve per delle notifiche nella notification bar (tali notifiche, mi dicono che il servizio e' "in buona salute"..IS RUNNING! ).
Tali servizi, pero', vorrei poterli stoppare a mio piacimento.
Allora, nella stessa Activity da cui li richiamo, ho implementato un altro Button che mi serve proprio a questo:
Codice (Java): [Seleziona]
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage("Are you sure you want to stop Services?")
                                .setCancelable(false)
                                .setPositiveButton("Yes",
                                                new DialogInterface.OnClickListener() {
                                                        public void onClick(DialogInterface dialog, int id) {
                                                                stopServices();
                                                        }
                                                })
                                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int id) {
                                                dialog.cancel();
                                        }
                                });
        Button stopServices = (Button) findViewById(R.id.Button_stop_services);
        stopServices.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                        AlertDialog alert = builder.create();
                        alert.show();
                }
        });
e la funzione per lo stop dei servizi e':
Codice (Java): [Seleziona]
// stop services
    private void stopServices(){
        stopService(new Intent(this, feasibilityEngine.class));
        stopService(new Intent(this, SOSFeeder.class));
        stopService(new Intent(this, taskScheduler.class));
    }

Quando faccio click succede una cosa strana: inizialmente le notifiche legate ai servizi, spariscono dalla notification bar, poi dopo un breve periodo riappaiono, cioe' i servizi ripartono da soli...  ???

La stopService(), agisce come l'ho intesa io, o sto trascurando qualcosa?

GRAZIE!  :-)

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:servizi "zombie"...
« Risposta #1 il: 16 Novembre 2010, 12:58:57 CET »
0
Più che il codice dei dialog sarebbe interessante vedere il codice dei servizi, nella fattispecie in metodi onStart e onStartCommand...

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #2 il: 16 Novembre 2010, 13:11:30 CET »
0
ho solo il metodo onStart e fa cosi:
Codice (Java): [Seleziona]
        @Override
        public int onStartCommand(Intent i, int flags, int startId){
                return Service.START_STICKY;
        }

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #3 il: 16 Novembre 2010, 13:12:07 CET »
0
...pardon, solo onStartCommand! :)

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:servizi "zombie"...
« Risposta #4 il: 16 Novembre 2010, 13:22:14 CET »
0
Prova a mettere dei tracciamenti all'interno del tuo servizio per capire un pochino lo stack delle chiamate. Ovviamente quello che succede è molto strano. Non è che si tratta di un problema di notifiche?

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #5 il: 16 Novembre 2010, 15:31:49 CET »
0
dentro la onCreate() del Service, faccio cosi:
Codice (Java): [Seleziona]
                private void startService(){
                        //Handler handler = new Handler();

                        int i = 0;
                        final int COUNTER = i;
                        //handler.postDelayed(new Runnable() {
                        Thread t = new Thread(){
                                public void run() {
                                        String ns = Context.NOTIFICATION_SERVICE;
                                        NotificationManager nm = (NotificationManager) getSystemService(ns);
                                        int icon = R.drawable.stat_notify_feasibility_engine;
                                        String tickerText = "Feasibility Engine RUN..." + COUNTER;
                                        long when = System.currentTimeMillis();
                                        Notification notification = new Notification(icon,
                                                        tickerText, when);
                                        Context context = getApplicationContext();
                                        CharSequence contentTitle = "Feasibility Engine State";
                                        CharSequence contentText = "Running!";
                                        Intent notificationIntent = new Intent(feasibilityEngine.this,
                                                        interfaceCSAMS.class);
                                        PendingIntent contentIntent = PendingIntent.getActivity(
                                                        context, 0, notificationIntent, 0);
                                        notification.setLatestEventInfo(context, contentTitle,
                                                        contentText, contentIntent);
                                        //notification.number++;
                                        nm.notify(MODULE_NOTIFICATION, notification);
                                }
                        };
                        t.start();
                        //}, 1000);
                }

P.s. notare che le righe commentate sono quelle che mi servivano per far partire il thread periodicamente (se ho capito bene l'utilizzo di postDelayed), funzionalita' che ho soppiantato con un semplice thread, che a questo punto, dovrebbe partire per la notifica e poi non fare nient'altro...

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:servizi "zombie"...
« Risposta #6 il: 16 Novembre 2010, 15:42:21 CET »
0
Hai provato a mettere dei tracciamenti nei vari metodi onCreate, onStartCommand, ecc? Giusto per essere sicuri che il service viene ristartato e il problema non è altrove?

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #7 il: 16 Novembre 2010, 15:46:55 CET »
0
dici di fare tracciamento nel Service?....non ho provato, ora lo faccio e vediamo...

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #8 il: 16 Novembre 2010, 15:58:26 CET »
0
Codice: [Seleziona]
11-16 15:54:29.126: INFO/ActivityManager(66): Displayed activity com.CSAMS/.interfaceCSAMS: 2685 ms (total 2685 ms)
11-16 15:54:33.246: VERBOSE/feasibilityEngine(18929): onCreate
11-16 15:54:33.286: VERBOSE/feasibilityEngine(18929): onStartCommand
11-16 15:54:38.147: VERBOSE/SOSFeeder(18929): onCreate
11-16 15:54:38.156: VERBOSE/SOSFeeder(18929): onStartCommand
11-16 15:54:39.286: DEBUG/dalvikvm(180): GC_EXPLICIT freed 157 objects / 11256 bytes in 112ms
11-16 15:54:43.156: VERBOSE/taskScheduler(18929): onCreate
11-16 15:54:43.176: VERBOSE/taskScheduler(18929): onStartCommand
11-16 15:54:44.266: DEBUG/dalvikvm(267): GC_EXPLICIT freed 46 objects / 2136 bytes in 86ms
11-16 15:54:48.206: WARN/InputManagerService(66): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@43fa3418
11-16 15:54:49.296: DEBUG/dalvikvm(126): GC_EXPLICIT freed 595 objects / 32928 bytes in 110ms
11-16 15:54:53.326: VERBOSE/feasibilityEngine(18929): onStartCommand
11-16 15:54:56.586: DEBUG/SntpClient(66): request time failed: java.net.SocketException: Address family not supported by protocol
11-16 15:54:58.336: VERBOSE/SOSFeeder(18929): onStartCommand
11-16 15:55:03.356: VERBOSE/taskScheduler(18929): onStartCommand
11-16 15:55:13.366: VERBOSE/feasibilityEngine(18929): onStartCommand
11-16 15:55:18.376: VERBOSE/SOSFeeder(18929): onStartCommand
11-16 15:55:23.386: VERBOSE/taskScheduler(18929): onStartCommand
11-16 15:55:33.406: VERBOSE/feasibilityEngine(18929): onStartCommand
11-16 15:55:38.416: VERBOSE/SOSFeeder(18929): onStartCommand
11-16 15:55:43.426: VERBOSE/taskScheduler(18929): onStartCommand
11-16 15:55:48.556: DEBUG/dalvikvm(18929): GC_EXPLICIT freed 1776 objects / 103544 bytes in 121ms
11-16 15:55:53.446: VERBOSE/feasibilityEngine(18929): onStartCommand


Il tracciamento mi fa vedere, da quando i servizi partono, che non vengono fatti partire una volta sola, ma in continuazione...forse ecco la causa.

MA PERCHE'?!
Puo' essere che, dato che i processi per ora non fanno nulla, il sistema operativo li distrugge e li ricrea continuamente a causa ti START_STICKY?  :-[

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:servizi "zombie"...
« Risposta #9 il: 16 Novembre 2010, 16:06:42 CET »
0
START_STICKY dovrebbe solamente dire al sistema di "farsi i fatti suoi" e lasciare ai client il compito di avviare e stoppare il servizio. Ma 'è anche da dire che onStartCommand non ti dice quando il servizio è stato creato e fatto partire, ti dice quando qualcuno chiama uno startService su di lui. O almeno così mi è parso di capire...
« Ultima modifica: 16 Novembre 2010, 16:08:32 CET da Ricky` »

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #10 il: 16 Novembre 2010, 16:11:19 CET »
0
START_STICKY dovrebbe solamente dire al sistema di "farsi i fatti suoi" e lasciare ai client il compito di avviare e stoppare il servizio. Ma 'è anche da dire che onStartCommand non ti dice quando il servizio è stato creato e fatto partire, ti dice quando qualcuno chiama uno startService su di lui. O almeno così mi è parso di capire...
e ok.
Ma allora cosa puo' rendere ciclica una chiamata che io non faccio?

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:servizi "zombie"...
« Risposta #11 il: 16 Novembre 2010, 16:12:25 CET »
0
Traccia il metodo dove chiami lo startService...

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #12 il: 16 Novembre 2010, 16:18:43 CET »
0
intanto ti posto anche il metodo che uso per far partire i processi, che magari e' li il macello e non lo vedo da solo...
Codice: [Seleziona]
final Handler handler = new Handler(){
            public void handleMessage(Message msg){
                    int total = msg.getData().getInt("tot");
                    progressDialog.setProgress(total);
                    if(total == 3){
                            dismissDialog(PROGRESS_DIALOG);
                            progressThread.setState(STATE_DONE);
                    }
            }
    };
   
    private class ProgressThread extends Thread{
            Handler mHandler;
            int total;
           
            ProgressThread(Handler h){
                    mHandler = h;
            }
           
            public void setState(int state){
                    mState = state;
            }
           
            public void run(){
                    mState = STATE_RUNNING;
                    total = 1;
                    while(mState == STATE_RUNNING){
                           
                            // start feasibility engine...
                            Intent i = new Intent(interfaceCSAMS.this, feasibilityEngine.class);
                        startService(i);
                            try{
                                    Thread.sleep(5000);
                            } catch(InterruptedException e) {
                                    Log.e("ERROR", "Thread interrupted");
                            }
                            Message msg = mHandler.obtainMessage();
                            Bundle b = new Bundle();
                            b.putInt("tot", total);
                            msg.setData(b);
                            mHandler.sendMessage(msg);
                            total++;
                           
                            // start sos feeder...
                            i = new Intent(interfaceCSAMS.this, SOSFeeder.class);
                        startService(i);
                            try{
                                    Thread.sleep(5000);
                            } catch(InterruptedException e) {
                                    Log.e("ERROR", "Thread interrupted");
                            }
                            msg = mHandler.obtainMessage();
                            //b = new Bundle();
                            b.putInt("tot", total);
                            msg.setData(b);
                            mHandler.sendMessage(msg);
                            total++;
                           
                            // start task scheduler
                            i = new Intent(interfaceCSAMS.this, taskScheduler.class);
                        startService(i);
                            try{
                                    Thread.sleep(5000);
                            } catch(InterruptedException e) {
                                    Log.e("ERROR", "Thread interrupted");
                            }
                            msg = mHandler.obtainMessage();
                            //b = new Bundle();
                            b.putInt("tot", total);
                            msg.setData(b);
                            mHandler.sendMessage(msg);
                            total++;
                           
                            //stop Activity
                            try{
                                    Thread.sleep(5000);
                            } catch(InterruptedException e) {
                                    Log.e("ERROR", "Thread interrupted");
                            }
                            finish();
                    }
            }
    }

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:servizi "zombie"...
« Risposta #13 il: 16 Novembre 2010, 16:21:06 CET »
0
Potresti spiegare qual'è il senso di quel codice? Vedo che dentro c'è un ciclo, magari è quello il problema.

Offline psicomant

  • Utente junior
  • **
  • Post: 95
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    OSX 10.6.5
Re:servizi "zombie"...
« Risposta #14 il: 16 Novembre 2010, 16:42:02 CET »
0
E' un ciclo che mi serve per mostrare un progress dialog...
In pratica si incrementa la variabile total ogni volta che faccio partire un service (quindi in sequenza partono tutti i service e alla fine la variabile total varra' 3). Tale variabile poi la passo all'Handler cosi

Codice (Java): [Seleziona]
Bundle b = new Bundle();
b.putInt("tot", total);

e se total == 3, dovrebbe fare

Codice (Java): [Seleziona]
dismissDialog(PROGRESS_DIALOG);
progressThread.setState(STATE_DONE);

e successivamente uscire dal ciclo e basta.