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

Android Discussion :

Obtenir la source d'une URL


Sujet :

Android

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2011
    Messages : 41
    Points : 29
    Points
    29
    Par défaut Obtenir la source d'une URL
    Bonjour,

    J'avais besoin pour une application d'un système très simple pour obtenir la source d'une URL. J'ai donc un peu bidouillé du code trouvé sur internet, ce qui m'a donné ça :

    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
     
    String get_source(String url)
        {
        	try {
     		   URL textUrl = new URL(url);
     		   BufferedReader bufferReader = new BufferedReader(new InputStreamReader(textUrl.openStream()));
     		   String StringBuffer;
     		         String stringText = "";
     		   while ((StringBuffer = bufferReader.readLine()) != null) {
     		    stringText += StringBuffer;
    		   }
    		         bufferReader.close();
    		         return stringText;
    		  } 
    	  catch (MalformedURLException e)
    		  {
    			  e.printStackTrace();
    			  return e.toString();
    		  } 
    	  catch (IOException e) {
    			  e.printStackTrace();
    			  return e.toString();
    		  }
        }

    Malheureusement, l'application plante quand je la lance en utilisant ça.

    Quelqu'un arriverait-il à m'indiquer la ou les erreurs, ou une solution plus simple ?

    Merci d'avance,

    7804j

  2. #2
    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
    Elle plante quoi ? Quand tu la lances où ?

    Non, trêve de plaisanterie... il faut un peu plus de détails... l'exception du logcat (avec la stack-trace détaillée) par exemple.

    Sinon sur le code... encore une fois... il y a trop d'exceptions catchées et mises sous silence (non répercutées).
    Au vu des exceptions d'ailleurs, je ne comprends pas pourquoi les catcher... (autant laisser la fonction les envoyer à l'appelant).

    Ensuite, e.printStackTrace() ca print ou ? Comme personne ne sait jamais répondre à cette question, on ne l'utilise jamais (d'autant que la fonction n'affiche que la stack-trace locale)... Sous Android on prefere:
    Log.e("MONTAG","J'ai une erreur pour faire toto",ex);
    Et bim... on a tout, l'exception, la stack-trace, directement dans le LogCat.

    Enfin, pour terminer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    BufferedReader bufferReader = new BufferedReader(new InputStreamReader(textUrl.openStream()));
    Le code est presque bien à part deux choses:
    1. Il n'y a pas de fermeture "propre" des ressources en cas d'exception justement (try / finally)
    2. Il n'y a pas de gestion du charset dans lequel la ressource est retournée... Donc ça risque de merdoyer sec pour les caractères "bizarres". A moins d'être sur que le résultat sera en ... ISO-8859-1 (ce qui est le défaut je crois)....
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2011
    Messages : 41
    Points : 29
    Points
    29
    Par défaut
    Euh... Oui c'est clair que j'ai pas vraiment pris soin de la gestion des erreurs mais que j'ai mis le try catch parce qu'il était obligatoire dans ce cas là.

    J'ai voulu indiquer les erreurs reçues du logCat dans le topic, mais j'ai plusieurs dizaines de lignes pas très compréhensibles et je ne sais pas trop quoi donner :/
    Mais voici tout de même toutes les erreurs reçues :
    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
     
    07-31 17:23:32.679: E/AndroidRuntime(2154): FATAL EXCEPTION: main
    07-31 17:23:32.679: E/AndroidRuntime(2154): android.os.NetworkOnMainThreadException
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at java.net.InetAddress.getAllByName(InetAddress.java:220)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at java.net.URL.openStream(URL.java:462)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at longest.game.LongestGameActivity.get_source(LongestGameActivity.java:4923)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at longest.game.LongestGameActivity$1.onClick(LongestGameActivity.java:115)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at android.view.View.performClick(View.java:3511)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at android.view.View$PerformClick.run(View.java:14105)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at android.os.Handler.handleCallback(Handler.java:605)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at android.os.Handler.dispatchMessage(Handler.java:92)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at android.os.Looper.loop(Looper.java:137)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at android.app.ActivityThread.main(ActivityThread.java:4424)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at java.lang.reflect.Method.invokeNative(Native Method)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at java.lang.reflect.Method.invoke(Method.java:511)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    07-31 17:23:32.679: E/AndroidRuntime(2154): 	at dalvik.system.NativeStart.main(Native Method)
    En l'occurrence, j'avais testé cette fonction avec une URL très simple, dans un cas très simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    new AlertDialog.Builder(LongestGameActivity.this).setMessage(get_source("http://geek-test.com/android/date")).setNeutralButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) {} }).setCancelable(false).show();
    Il n'existe pas une fonction déjà existante faisant quelque chose de similaire ? Ca me semblait pourtant assez basique :/

  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
    Hop, NetworkOnMainThreadException, c'est pas bien

    Toi, tu cibles HoneyComb ou supérieur, et tu fais un appel réseau sur le thread principal (l'exception est bien nommée). C'est une très mauvaise pratique car tu gèles l'interface utilisateur le temps de ton traitement. Plus largement, ne pas faire traitement longue dans le thread graphique.

    Déplace ce traitement dans un thread à part ou dans une AsyncTask, et ça devrait mieux aller. Le but est de ne pas faire ce traitement dans le thread graphique pour ne pas freezer l'interface.
    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
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2011
    Messages : 41
    Points : 29
    Points
    29
    Par défaut
    Heu... Merci pour ces conseils certainement très avisés, mais ça devient malheureusement un peu compliqué pour moi :/
    En fait, j'ai jamais vraiment géré plusieurs threads ou utilisé AsyncTask, etc. ni vraiment tous les outils liés à aux connexions http, etc.

    N'y a-t-il vraiment pas un moyen de faire ça vraiment très simplement, sans devoir toucher à tout ça, pour récupérer une source ?

    En fait, à la base, il me faut juste récupérer la date du jour. Comme la date du smartphone n'est pas fiable, je voulais passer par internet :/

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par 7804j Voir le message
    En fait, j'ai jamais vraiment géré plusieurs threads ou utilisé AsyncTask, etc. ni vraiment tous les outils liés à aux connexions http, etc.
    Et bien, c'est le moment d'apprendre

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2011
    Messages : 41
    Points : 29
    Points
    29
    Par défaut
    J'ai trouvé une solution pas très propre, mais qui a marché :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     if(Build.VERSION.SDK_INT > 8)
            {
    	        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    	        StrictMode.setThreadPolicy(policy);
            }

  8. #8
    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
    Oui mais non

    En fait, un appel réseau dans le thread de l'UI est Interdit depuis le début d'Android... Il était juste pas vérifié par le système qui partait du principe que les développeurs allait programmer propre.... Du coup depuis Android3.0 bim... NOMTE lors d'un appel réseau sur le thread principal.

    La seule chose que tu vas gagner avec le bout de code au dessus est au pire de faire l'application cracher violemment (Application Not Responding) si l'accès réseau est lent.... Et au mieux, t'autoriser à faire quelque chose d'interdit.

    ASyncTask est vraiment très simple à utiliser, et ne nécessite aucune connaissance particulière sur le multi-threading... En fait la fonction initiale est une excellente candidate pour devenir une AsyncTask à part entière... Deux fonctions à implémenter... et ça roule...


    Par contre je continue de dire concernant les exceptions que
    [le try/catch] qu'il était obligatoire dans ce cas là.
    C'est pas vrai... !!! Non sans déconner, vu la fonction il n'est pas du tout obligatoire ! Au contraire, il est même obligatoire de passer ces exception à la fonction appelante....
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  9. #9
    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
    On a un problème ?
    Pas grave, on le planque.

    Tu corriges l'erreur en la supprimant, pas en corrigeant sa source.

    J'espère honnêtement que les utilisateurs de ton application ne sont pas regardant sur la qualité.

    Sinon ... tu écris
    Citation Envoyé par 7804j
    En fait, j'ai jamais vraiment géré plusieurs threads ou utilisé AsyncTask, etc. ni vraiment tous les outils liés à aux connexions http, etc.
    Dans ton code, il y a un appel HTTP, donc c'est à ta portée ... comme le reste de cette liste, sans grand doute.

    Regarde les AsyncTask, c'est extrêmement simple.
    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

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2011
    Messages : 41
    Points : 29
    Points
    29
    Par défaut
    Sinon ... tu écris
    Citation:
    Envoyé par 7804j
    En fait, j'ai jamais vraiment géré plusieurs threads ou utilisé AsyncTask, etc. ni vraiment tous les outils liés à aux connexions http, etc.
    Dans ton code, il y a un appel HTTP, donc c'est à ta portée ... comme le reste de cette liste, sans grand doute.

    Regarde les AsyncTask, c'est extrêmement simple.
    Quand je dis que je maîtrise pas, c'est parce que j'ai simplement utilisé ce que j'ai trouvé sur internet. Ce n'est pas moi qui ai construit cette fonction, je l'ai juste à peine modifiée. Enfin bon, c'est pas grave.

    J'ai quand même été faire un tour sur les AsyncTasks. C'est pas forcément si simple que ça quand on y a jamais touché, mais ça reste assez compréhensible. Par contre, je n'ai pas saisi comment on faisait pour avoir une valeur de retour avec :/

    Soit la classe suivante :
    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
     
    class MyTask extends AsyncTask<Void, Void, String>
    {
     
        String textResult;
     
        @Override
        protected String doInBackground(Void... params) {
     
           //Récupération du code source, plein de calculs, etc.
     
         return textResult;
     
        }
     
     }
    Et mon code d'avant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    new AlertDialog.Builder(LongestGameActivity.this).setMessage( new MyTask().execute()).setNeutralButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) {} }).setCancelable(false).show();
    En fait, je voudrais que l'alertDialog m'affiche la valeur de retour de l'AsyncTask, mais ça fonctionne bien sûr pas. Comment doit-on faire pour récupérer la valeur de retour d'une AsynkTask ?

  11. #11
    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
    Ben c'est tout le principe: c'est ASYNChrone....

    Donc le code n'est pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    new AlertDialog.Builder(LongestGameActivity.this).setMessage( new MyTask().execute()).setNeutralButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) {} }).setCancelable(false).show();
    Dans la classe de l'activité (histoire d'avoir un pointeur sur l'activité 'natif'):
    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
     
    public class LongestGameActivity extends Activity
    {
       // Ici les paramètres sont des URLs sous forme de String...
       class MyTask exends AsyncTask<String,Void,String>
       {
           // La partie executée en background
           public String doInBackground(String ... urls)
           {
                  return get_source(urls[0]);
           }
     
           // La partie executée dans le thread UI
           @Override
           public void onPostExecute(String textResult) {
              // pas besoin de stocker le résultat de doInBackground il est passé ici !
              if (textResult != null) {
                 new AlertDialog.Builder(LongestGameActivity.this)
                        .setMessage( textResult )
                        .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
                                      public void onClick(DialogInterface arg0, int arg1) {}      
                                       })
                        .setCancelable(false)
                        .show();
             }
          }
     
          ...
     
     
         // pour lancer la task (et afficher la boite de dialogue)
         (new MyTask(monUrl)).execute();
     }
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

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

Discussions similaires

  1. [WD18] Obtenir fichier csv depuis une url
    Par lerorodu51 dans le forum WinDev
    Réponses: 4
    Dernier message: 10/01/2014, 14h48
  2. obtenir le contenu d'une url
    Par fraoustin dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/07/2011, 20h48
  3. VB6 Connection à une base de données dont la source est une adresse url
    Par yangoal25 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 13/11/2006, 18h47
  4. [URL] Obtenir le contenu d'une url
    Par cterra dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 08/08/2006, 10h01
  5. [Reseau] Récupérer le code source d'une URL
    Par gogolpexe dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 29/06/2005, 14h06

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