Autore Topic: Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?  (Letto 851 volte)

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Ciao a tutti sn alle prese con una questione che mi risulta poco chiara, o meglio pensavo di aver capito a cosa servon i service ma poi la pratica mi ha smentito :)

QUesto è i codice
Codice (Java): [Seleziona]
public class DownloadService extends Service
{
        private static final int HELLO_ID = 1;
        public MetodiUtili mu;
        public PendingIntent pendingIntent;
        public Notification notification;
        public NotificationManager notificationManager;
        private int progress = 0;

        @Override
        public IBinder onBind(Intent arg0)
        {
                // TODO Auto-generated method stub
                return null;
        }
       
        @Override
        public void onCreate()
        {
                super.onCreate();
                System.out.println("son dentro al servizio");
               
               
                //set the download URL, a url that points to a file on the internet
            //this is the file to be downloaded
                mu = new MetodiUtili();
                if (mu.canReadFromExternalStorage())
                {
                        try
                        {
                        URL url = new URL("http://10.47.103.162:8080/applicazioni/prova.zip");
                        System.out.println("creato url");
                        //create the new connection
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        System.out.println("creato conn");
                        //set up some things on the connection
                        conn.setRequestMethod("GET");
                        conn.setDoOutput(true);
                        conn.setDoInput(true);
                        conn.setRequestProperty("content-type", "binary/data");
                        System.out.println("fatto un po di set");
                        System.out.println("fatto la connessione vera");
                        File SDCardRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
                            //String percorso = this.getFilesDir().getAbsolutePath();
                            //System.out.println("percorso dove salvo = "+percorso);
                            //create a new file, specifying the path, and the filename
                            //which we want to save the file as.
                       
                            boolean success = (SDCardRoot).mkdirs();
                            System.out.println("percorso creato = "+success);
                            File file = new File(SDCardRoot,"prova.zip");
                            //System.out.println("do nome al file che salverò");
                            //file.createNewFile();
                           
                            System.out.println("do nome al file che salverò");
                            //this will be used to write the downloaded data into the file we created
                            InputStream inputStream = conn.getInputStream();
                            System.out.println("imput stream");
                            FileOutputStream fileOutput = new FileOutputStream(file,false);
                            System.out.println("output stream");
                            //this will be used in reading the data from the internet
                           
                            lanciaNotification_download();
                            System.out.println("tornato dal metodo della notification");
                             
                            //this is the total size of the file
                            int totalSize = conn.getContentLength();
                            System.out.println("grandezza file = "+ totalSize);
                            //variable to store total downloaded bytes
                            int downloadedSize = 0;
                        //create a buffer...
                        byte[] buffer = new byte[1024];
                        int bufferLength = 0; //used to store a temporary size of the buffer
                        //now, read through the input buffer and write the contents to the file
                        while ( (bufferLength = inputStream.read(buffer)) > 0 )
                        {
                                System.out.println("dentro il while total e scaricato = "+totalSize+ "mmm "+downloadedSize);
                                add the data in the buffer to the file in the file output stream (the file on the sd card
                            fileOutput.write(buffer, 0, bufferLength);
                            add up the size so we know how much is downloaded
                            downloadedSize += bufferLength;
                            progress = (int)(totalSize/downloadedSize);
                            notification.contentView.setProgressBar(R.id.status_progress, 100, progress, false);

                           inform the progress bar of updates in progress
                           notificationManager.notify(42, notification);
                            //this is where you would do something to report the prgress, like this maybe
                            //updateProgress(downloadedSize, totalSize);
                        }
                        System.out.println("fato tutto chiudo");
                            //close the output stream when done
                        //notificationManager.cancel(42);
                        fileOutput.close();
                            inputStream.close();
                                //catch some possible errors...
                        //}
                                //else System.out.println("non posso o leggere o scriver la sd");
                        }
                        catch (MalformedURLException e)
                    {
                            e.printStackTrace();
                    }
                    catch (IOException e)
                    {
                            e.printStackTrace();
                    }
                }
                else System.out.println("Non posso scrivere o legger dalla sd");
               
        }
        @Override
        public void onDestroy()
        {
                super.onDestroy();
               
                Log.i("ServiceDemo01", "Servizio arrestato");
        }
       
        public void lanciaNotification_download()
        {
               
                Intent intent = new Intent(this, Application_activity.class);
        pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        // configure the notification
        notification = new Notification(R.drawable.icon, "simulating a download", System.currentTimeMillis());
        notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
        notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.notification_download_layout);
        notification.contentIntent = pendingIntent;
        notification.contentView.setImageViewResource(R.id.status_icon, R.drawable.ic_menu_save);
        notification.contentView.setTextViewText(R.id.status_text, "simulation in progress");
        notification.contentView.setProgressBar(R.id.status_progress, 100, progress, false);

        notificationManager = (NotificationManager) getApplicationContext().getSystemService(
                getApplicationContext().NOTIFICATION_SERVICE);

        notificationManager.notify(42, notification);
        }
}

COsa devo fare:

In pratica sn dentro un activity che si chiama Application_activity simile a quando nel market android si sta guardando il dettaglio di una applicazione. Quando clicco sul bottone download deve iniziare a scaricare un file .zip e salvarlo sulla sd. Inoltre deve segnalare nella notification bar che il download è iniziato e se espando la notification bar devo vedere la barra cn la percentuale di completamento. Chiaramente intanto che questo accade deco esser libero di continuare a utilizzare la mia app.

Segue ho pensato a questo. Quando clicco su Download viene chiamato tramite intent il service sopra allegato, in quanto da quel che ho capito servon proprio a eseguire lavori in background, e dato che la mia notification deve avere la barra di download cerco di crearne una cn un layout customizzato perchè in quelle standard la barra nn c'è ==> ho sperimentato assieme 2 concetti nuovi per me, i service e le notification. Il risultato è che il tutto nn funziona come dovrebbe.

Ho quindi commentato la parte in cui creo lancio il metodo che crea la notification pensando che il problema fosse  li(e chiaramente commentato anche nel while la parte dove aggiorno la barra) ma il risultato è stato inaspettato.
In pratica il service parte, inizia a scaricare lo zip ma per tutto il tempo in cui scarica (10 sec, quindi sufficienti a far uscire il mex "l'applicazione nn risponde") la gui resta inutilizzabile cn il pulsante donwload evidenziato in arancione e premuto.

Da qui il mio dubbio. Ma i service nn sn una sorta di thread fichi, ovvero mentre loro fan quel che devon le activity che li han chiamati posson continuare a far quel che vogliono?
Se no vuol dire che devo mettere un thread dentro la classe service o gli faccio implementare runnable, ma in questo caso nn vedo il guadagno, avrei potuto benissimo fare una normale classe java che estende thread..

Inoltre se provo quando ha finito a ricliccare download nn fa più niente......questo perchè se non killo il service questo rimane aperto a "fondo codice" ovvero nn lo riesegure?

Offline Jordano

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Nexus S
  • Sistema operativo:
    Ubuntu
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #1 il: 07 Giugno 2011, 22:52:32 CEST »
+1
ho dato solo una sfuggita al codice, però ti posso dire che i Service non sono ne un nuovo processo ne un thread separato. Quello che fai nel service viene eseguito sul main thread e quindi ti blocca l'interfaccia grafica.

Dai un occhio agli IntentService che svolgono il loro compito in un thread separato senza dover implementare tutta la cosa dei thread.

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #2 il: 07 Giugno 2011, 23:31:00 CEST »
0
Ok quindi in pratica i service nn includon un nuovo thread al loro interno ma gli inetntservice si ....... interessante...........ma quindi l'utilità dei srvice base qual'è rispetto a usare una classe thread? Se mentre il download è partito io chiudo l'applicazione il doqnload continua se è in un service o si chiude? Perchè se nell'android market io lancio un download e poi lo chido il tutto continua...........e così vorrei io


Gli intent service fan al caso mio se nn che nelle prime righe della documentazione dice:
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.

Quindi se io do il via a un download e poi vado su un altra app e clicco per scaricare anche quella me lo mette in coda invece che avviare in parallelo? Questo va meno bene.......

Offline Jordano

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Nexus S
  • Sistema operativo:
    Ubuntu
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #3 il: 07 Giugno 2011, 23:35:51 CEST »
0
un service è un componente senza interfaccia grafica dentro il quale puoi svolgere compiti anche di lunga durata, se fai un thread dentro a un activity e la chiudi poi non sei sicuro che il sistema ti mantenga in vita il processo dentro cui stai svolgendo il lavoro, perchè potrebbe sgomberare per far risorse per un altra applicazione che sta usando l'utente.

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #4 il: 07 Giugno 2011, 23:55:13 CEST »
0
Capitp, xò scusa allora quando si crea un service al suo interno si deve sempre creare anche un nuovo thread............è vero che le azioni fatte dal service nn sempre sn lunghe come scaricare un file, magari è una cosa da un secondo,ma cmq x quel secondo la tua gui non risponderà...........quindi a logica l'univo caso in cui nn metterei un thread in un service è quando questo sta in background senza che l'utente abbia più una gui cn cui interagire, della serie chiudo l'app che fa ascoltare la musa quindi nn ho più la gui che si bloccherebbe, e intanto la musica va in sottofondo..........o sbaglio......

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #5 il: 08 Giugno 2011, 00:30:37 CEST »
0
sgotenks per favore evita di scrivere a mo' di sms, qui non paghi per i caratteri che invii :)

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #6 il: 08 Giugno 2011, 00:33:40 CEST »
0
Sorry questione di abitune.....stop.....non lo farò più stop............passo in modalità telegramma :-P

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #7 il: 10 Giugno 2011, 19:20:39 CEST »
0
Sn riuscito in parte a fare il tutto.............però ho un problema con questi intent service. In pratica come dicon le specifiche han una coda che gestisce le richieste una alla volta. Ovvero se clicco 2 volte su download parte l'oncreate dell'intent service, poi l'onhandleintent che crea una notification e fa partire il download.
Il problema è che quando clicco di nuovo su download questo viene accodato all'altro, quindi finito di scaricare il primo file l'onhandle riparte da capoa  a fare il codice e scarica il secondo file. QUesto va bene a me però vorrei che per lo meno, quando clicco su download venisse lancoato una seconda notification e che quindi nella barra delle notifications mi mostrasse l'iconcina del download cn il 2, ma questo nn accade perchp anche la notification è creata nell' onhandle quindi, non lancia la seconda finchè non ha finito il primo ciclo.

Volevo quindi sapere se c'è un modo per interagire con la coda che l'intent service crea automaticamente, del tipo se ricevi un nuovo intent accodalo e lancoa un'altra notification.......poi i download falli pure uno alla volta.............

Inoltre volevo capire se tutto l'intentservice sta in un nuovo worker thread o solo la parte di codice nell'handle, e se dall'intet service posso modificare la gui o devo usare un handler come x un thread qualunque per comunicare cn la gui.


Grazie

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Re:Ma cn i service bisogna cmq usare i thread perchè nn blocchino la gui?
« Risposta #8 il: 13 Giugno 2011, 15:44:35 CEST »
0
Nessuno mi sa aiutare? La documentazione a riguardo non dice assolutamente niente........