IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API standards et tierces Android Discussion :

Service qui plante dès que la connexion est perdue


Sujet :

API standards et tierces Android

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 36
    Points : 24
    Points
    24
    Par défaut Service qui plante dès que la connexion est perdue
    bonjour

    je débute dans la programmation android.

    j'aimerais faire tourner un service en background.
    ce service récupère toutes les 5 minutes le md5 d'une image en ligne.
    tout fonctionne mais cela crash quand l'appareil / l'émulateur n'est pas connecté.

    j'ai mis le code complet du service :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    package com.mypack.otw;
    
    import java.io.InputStream;
    import java.net.URL;
    import java.security.DigestInputStream;
    import java.security.MessageDigest;
    import java.util.Timer;
    import java.util.TimerTask;
    
    import android.annotation.SuppressLint;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.util.Log;
    import android.widget.Toast;
    
    public class TestService extends Service {
    
        public TestService()  {
        	
        }
        
        private static Timer timer = new Timer(); 
        @SuppressWarnings("unused")
    	private Context ctx;
        public static String hash = "xxx";
        
        public static String checkHashURL(String input) {
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                
                InputStream is = new URL(input).openStream();
    
                
                try {
                    is = new DigestInputStream(is, md);
    
                    while (is.read() != -1) {
                        ;
                    }
                } catch (Exception vv){
                	is.close();
                	throw new RuntimeException(vv);
                }
                 
                finally {
                    is.close();
                }
                byte[] digest = md.digest();
                StringBuffer sb = new StringBuffer();
    
                for (int i = 0; i < digest.length; i++) {
                    sb.append(
                            Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(
                                    1));
                }
                
                return sb.toString();
                
    
              
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
        
        
    
        @Override
        public IBinder onBind(Intent intent) {
               // TODO: Return the communication channel to the service.
               throw new UnsupportedOperationException("Not yet implemented");
        }
        @SuppressLint("ShowToast") @Override
        public void onCreate()  {  
        	
               // TODO Auto-generated method stub
        	   Toast.makeText(getApplicationContext(), "Service Created",1).show();
        	   Log.i("Le service a été créé", "Service_created");
               super.onCreate();
        }
        
        
        private class mainTask extends TimerTask
        { 
            public void run() 
            {
            	//hash = checkHashURL("http://www.url_enquestion/example.jpg");
            	toastHandler.sendEmptyMessage(0);
            }
        }    
      
       
        @SuppressLint("ShowToast") @Override
        public void onDestroy() {
               // TODO Auto-generated method stub
               Toast.makeText(getApplicationContext(), "Service Destroy",1).show();
               Log.i("Le service a été démoli", "Service_destroyed");
               super.onDestroy();
        }
       
        @SuppressLint("ShowToast") @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
               // TODO Auto-generated method stub
               Toast.makeText(getApplicationContext(), "Service Working",1).show();
               timer.scheduleAtFixedRate(new mainTask(), 0, 5000);
               Log.i("Le service tourne", "Service_OK");
               return super.onStartCommand(intent, flags, startId);
        }
        
    
        
        @SuppressLint("HandlerLeak") private final Handler toastHandler = new Handler()
        {
            @Override
            public void handleMessage(Message msg)
            {
            	hash = checkHashURL("http://www.url_enquestion/example.jpg");
               // Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_SHORT).show();
                try {
                	if (hash != null){
                	Toast.makeText(getApplicationContext(), "Hash is " + hash ,1).show();
                	}
                } catch (Exception em){
                	em.printStackTrace();
                }
            }
        };    
      
        
    }
    j'ai mis en rouge la ligne qui semblait provoquer l'erreur.
    l'url apparait deux fois parce que google suggérait un problème de synchro / threads (j'ai bêtement essayé les deux endroits).
    en résumé, je veux bien qu'il ne récupère pas le hash offline, mais j'aimerais qu'il continue à tourner.

    merci pour vos réponses

  2. #2
    Membre éclairé
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Points : 832
    Points
    832
    Par défaut
    Salut,
    Il nous faudrait le log de l'erreur, qui est dispo dans le logcat de ton IDE, si tu veux qu'on puisse t'aider efficacement.

    http://nbenbourahla.developpez.com/t...s-application/
    "Quand la lune n'est pas là, la nuit mène une existence obscure"

  3. #3
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 36
    Points : 24
    Points
    24
    Par défaut
    merci LeBzul

    je pense qu'il n'est pas complet parce que le virtual device est sur une autre partoche mais il donne des indications intéressantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    11-26 03:35:45.020: D/dalvikvm(795): GC_FOR_ALLOC freed 64K, 5% free 2901K/3044K, paused 230ms, total 231ms
    11-26 03:35:45.020: I/dalvikvm-heap(795): Grow heap (frag case) to 3.967MB for 1113568-byte allocation
    11-26 03:35:45.330: D/dalvikvm(795): GC_FOR_ALLOC freed <1K, 4% free 3988K/4132K, paused 289ms, total 289ms
    11-26 03:35:45.790: W/ContextImpl(795): Implicit intents with startService are not safe: Intent { act=com.MyApp.otw.TestService } android.content.ContextWrapper.startService:494 com.MyApp.otw.MainActivity.onCreate:37 android.app.Activity.performCreate:5231 
    11-26 03:35:46.100: I/Choreographer(795): Skipped 36 frames!  The application may be doing too much work on its main thread.
    11-26 03:35:46.900: D/gralloc_goldfish(795): Emulator without GPU emulation detected.
    11-26 03:36:16.030: I/Le service a été créé(795): Service_created
    11-26 03:36:16.050: I/Le service tourne(795): Service_OK
    11-26 03:36:16.390: D/AndroidRuntime(795): Shutting down VM
    11-26 03:36:16.390: W/dalvikvm(795): threadid=1: thread exiting with uncaught exception (group=0xb3a7bba8)
    11-26 03:36:16.430: E/AndroidRuntime(795): FATAL EXCEPTION: main
    11-26 03:36:16.430: E/AndroidRuntime(795): Process: com.MyApp.otw, PID: 795
    11-26 03:36:16.430: E/AndroidRuntime(795): java.lang.RuntimeException: android.os.NetworkOnMainThreadException
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.MyApp.otw.TestService.checkHashURL(TestService.java:66)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.MyApp.otw.TestService$1.handleMessage(TestService.java:121)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at android.os.Handler.dispatchMessage(Handler.java:102)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at android.os.Looper.loop(Looper.java:136)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at android.app.ActivityThread.main(ActivityThread.java:5017)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at java.lang.reflect.Method.invokeNative(Native Method)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at java.lang.reflect.Method.invoke(Method.java:515)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at dalvik.system.NativeStart.main(Native Method)
    11-26 03:36:16.430: E/AndroidRuntime(795): Caused by: android.os.NetworkOnMainThreadException
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at java.net.InetAddress.getAllByName(InetAddress.java:214)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at java.net.URL.openStream(URL.java:470)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	at com.MyApp.otw.TestService.checkHashURL(TestService.java:35)
    11-26 03:36:16.430: E/AndroidRuntime(795): 	... 9 more
    11-26 03:39:18.050: I/Process(795): Sending signal. PID: 795 SIG: 9
    j'ai évidemment configuré un proxy bidon parce que tout se passe bien quand la connexion est active.

    la commande "db logcat -d > logcat.txt" ne s'exécute pas non plus (waiting for device) mais si c'est vraiment nécessaire, il doit y avoir un path à configurer qqe part pour la VM.
    j'ai essayé d'ajouter un thread, mais c'est aussi compliqué pour moi en java qu'en c++, surtout sur cette base de code.

    bonne journée

  4. #4
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Ah, ça faisait longtemps

    NetworkOnMainThreadException -> On ne fait JAMAIS d'appel réseau (et par extension : d'opération potentiellement longue) dans le thread graphique pour ne pas le geler. C'est une mauvaise pratique générale et assez répandue sur Android < 3.0, tellement répandu que cette exception a été mise en place.

    Donc, passe par un Thread et un pattern Observer pour tes appels réseaux, ou une AsyncTask.
    C'est Android, PAS Androïd, ou Androïde didiou !
    Le premier est un OS, le second est la mauvaise orthographe du troisième, un mot français désignant un robot à forme humaine.

    Membre du comité contre la phrase "ça marche PAS" en titre et/ou explication de problème.

    N'oubliez pas de consulter les FAQ Android et les cours et tutoriels Android

  5. #5
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 36
    Points : 24
    Points
    24
    Par défaut
    merci pour la confirmation Hizin.

    je vais chipoter pour l'implémenter mais tu me confirmes ce que google disait... et que je ne voulais pas voir.


    ton message est très clair.


    je reviens si je galère

  6. #6
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Passe par une AsyncTask, ce n'est pas très complexe à mettre en place, et les opérations se font naturellement dans le thread graphique ou à part respectivement, dépendant des méthodes
    C'est Android, PAS Androïd, ou Androïde didiou !
    Le premier est un OS, le second est la mauvaise orthographe du troisième, un mot français désignant un robot à forme humaine.

    Membre du comité contre la phrase "ça marche PAS" en titre et/ou explication de problème.

    N'oubliez pas de consulter les FAQ Android et les cours et tutoriels Android

  7. #7
    Membre éclairé
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Points : 832
    Points
    832
    Par défaut
    Je suis un peu étonné qu'on ai besoin de lancer cette tache dans un thread à part;
    Pour moi, mais je me trompe surement, un Service est justement un thread (parmi d'autre type de thread) détaché de l'application permettant d'effectuer une tâche lourde sans bloquer le mainThread.
    Comment se fait il alors qu'il ai besoin de créer un autre thread dans le service ?
    Il y une subtilité, ou je suis à totalement coté de la plaque ?
    "Quand la lune n'est pas là, la nuit mène une existence obscure"

  8. #8
    Expert confirmé
    Avatar de Hephaistos007
    Profil pro
    Enseignant Chercheur
    Inscrit en
    Décembre 2004
    Messages
    2 493
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 493
    Points : 4 166
    Points
    4 166
    Par défaut
    Il faut étendre android.app.IntentService pour éviter ce problème de thread.
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes --- devise SHADOKS

    Kit de survie Android : mon guide pour apprendre à programmer sur Android, mon tutoriel sur les web services et enfin l'outil en ligne pour vous faire gagner du temps - N'oubliez pas de consulter la FAQ Android

  9. #9
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par LeBzul Voir le message
    Je suis un peu étonné qu'on ai besoin de lancer cette tache dans un thread à part;
    Pour moi, mais je me trompe surement, un Service est justement un thread (parmi d'autre type de thread) détaché de l'application permettant d'effectuer une tâche lourde sans bloquer le mainThread.
    Comment se fait il alors qu'il ai besoin de créer un autre thread dans le service ?
    Il y une subtilité, ou je suis à totalement coté de la plaque ?
    Un service *n'est pas un thread*. Un service est une activité qui n'utilise pas d'interface. point barre.
    Le service réagit aux intents comme les activités (d'ailleurs lancer un service se fait par intents), et se programme exactement comme une activité... (contexte, etc...). L'unique est qu'il n'y a pas de View / Window attachée, et par conséquent n'a pas de gestion de resume/pause start/stop (qui sont des réactions purement d'UI), juste "create/destroy".

    De la même manière qu'une activité, le jour ou le service reçoit un "intent" il doit y répondre *le plus vite possible*. Si le traitement est potentiellement long, alors il *faut* faire un thread.

    A noter que le même genre de choses doivent être faites dans les "receiver" (broadcastreceiver par exemple).


    Beaucoup de gens associent les termes androids aux termes "windows":
    Une "application" Android n'est *pas* une application au sens ordinateur desktop.
    Un "service" Android n'est *pas* un service au sens Windows.
    etc...
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  10. #10
    Membre éclairé
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Points : 832
    Points
    832
    Par défaut
    Merci Nicroman pour cette précision.
    Je ne voyais pas le Service de cette manière.

    Beaucoup de gens associent les termes androids aux termes "windows"
    Je pense que l'on associe instinctivement un terme à se que l'on connait déjà, surtout s'il n'a pas de raison évidente d'être différent.
    "Quand la lune n'est pas là, la nuit mène une existence obscure"

  11. #11
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 36
    Points : 24
    Points
    24
    Par défaut
    salut

    c'est bon.
    ^^

    merci pour vos réponses et toutes les conversations qui en ont découlées.

    donc, j'ai commencé par suivre tous les conseils (AsyncTask) mais cela se plantait toujours en cas de déconnexion / changement de réseau.
    alors, quitte à passer un chouia plus de temps, j'ai mis ce beau monde dans un thread... et ça se plantait toujours de la même façon (je vous passe toutes mes autres erreurs de syntaxe, etc...).
    j'avais peu de temps donc j'ai dû y regarder quelques minutes par jour.

    finalement, j'ai "googlisé" le logcat et suis tombé sur un truc du genre : http://developer.android.com/referen...Exception.html et "poum paf pif", c'est nickel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     try {
    				hash = checkHashURL("http://MaSuperImageQuiDechire.jpg");
    			} catch (InterruptedIOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}

    bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Service qui plante si démarré au boot
    Par RaphAstronome dans le forum Android
    Réponses: 1
    Dernier message: 12/05/2013, 17h23
  2. Qu'est-ce qui peut expliquer que la suppression est longue ?
    Par oneagaindoguys dans le forum Requêtes
    Réponses: 3
    Dernier message: 03/03/2011, 14h08
  3. [MySQL] Serveur MySQL qui plante car trop de connexions
    Par Dsphinx dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 16/02/2011, 00h50
  4. Réponses: 1
    Dernier message: 18/02/2009, 18h32
  5. Réponses: 3
    Dernier message: 10/08/2005, 11h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo