CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[Android] Problème Requête HTTP

TheRealMarco
TheRealMarco
Niveau 13
27 juillet 2015 à 19:06:15

Bonjour,

Je viens tout juste de commencer à développer en java, j'ai besoin de faire une application qui récupère le code HTML de page internet. J'ai essayé plusieurs codes sur internet, jamais l'application n'arrive à se connecter sur internet.

En tombant sur ce topic, j'ai vu qu'il fallait rajouter au manifest une permission :

https://openclassrooms.com/forum/sujet/recuperer-les-donnees-d-un-site-web-avec-android

Ce que j'ai rajouté :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="hanakim.comparateur" >
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application [...]

Le code qui me pose problème :

public String getTextFromURL(String url)
    {
        String sortie = "";
        try {
            URL oracle = new URL("http://www.oracle.com/");
            BufferedReader in = new BufferedReader( new InputStreamReader([oracle.openStream()]));
 
            String inputLine;
            while ((inputLine = in.readLine()) != null)
                sortie += inputLine;
            in.close();
        }
        catch (Exception ex) {
            sortie += "Erreur :";
            sortie += ex.getMessage();
        }
        return sortie;
    }

La partie de code entre crochet fait inéluctablement planté l'application.

J'ai essayé avec HttpURLConnection, mais quand l'application arrive à la ligne .openConnection();, il plante aussi.

Quelqu'un aurai une idée de mon problème ?

J'ai utilisé un émulateur et un vrai smartphone, dans les deux cas, l'exception affiché est "null". Si je ne mets pas de try catch, l'application plante systématiquement. L'émulateur et le smartphone étaient connectés à internet. Sur le smartphone, quand la requête devait s'effectuer, un message "Protection de la vie privée" apparaissait en haut, sans plus d'explications.

Merci d'avance pour votre aide.

Xavier591
Xavier591
Niveau 5
27 juillet 2015 à 19:16:38

Salut,

Je ne m'y connais pas du tout en java mais il y a une ligne qui m'intrigue :
BufferedReader in = new BufferedReader( new InputStreamReader([oracle.openStream()]));

Comment peux-tu passer en argument une fonction entre [ ] ? Il doit y avoir une erreur ...

Message édité le 27 juillet 2015 à 19:17:15 par Xavier591
Bunyan
Bunyan
Niveau 17
27 juillet 2015 à 19:21:35

Bon, y'a pas l'erreur mais je parie cent balles et un mars que c'est une NetworkOnMainThreadException.

Mets un Log.e(TAG, message, e); dans ton catch, où TAG est une String permettant de filtrer le LogCat, message est une String lambda affichant le message que tu veux et e étant l'exception.

Version courte : fait tes appels réseaux dans un processus séparé, quel que soit la plate-forme et le langage.

Version longue : cette exception est apparue avec Android 3 puisque beaucoup de développeurs ont la très mauvaise habitude de faire des opérations potentiellement longue dans le thread graphique (ou thread principal), ce qui revient à geler l'interface graphique (ce qui est, en terme d'utilisabilité et d'ergonomie, un zéro pointé).
Les opérations réseaux pouvant être potentiellement longue (quelques millisecondes quand tout va bien à "infini" si les temps d'attentes ont été paramétré extrêmement haut en amont comme en aval), celes-ci sont détectées dans le thread graphique et lèvent cette exception.
La façon de résoudre ce problème est d'utiliser un autre thread pour faire cet appel réseau (et par extension : ne faire aucune opération potentiellement longue dans le thread graphique).
Pour se faire, tu peux utiliser la classe Thread ou, beaucoup plus simplement, la classe AsyncTask, qui est un sucre syntaxique permettant de préparer l'interface (dans la méthode onPreExecute), de réaliser le traitement dans un autre thread (grâce à la méthode onBackground qui s'exécute dans un Thread) puis de mettre à jour l'interface une fois finie (grâce à la méthode onPostExecute et au pattern Observer).

EDIT : la remarque de Xavier591 me paraît correct aussi (je n'ai absolument pas jeté un oeil au code, ce que je fais toujours lorsque j'ai des données incomplètes pour résoudre un problème).

Message édité le 27 juillet 2015 à 19:24:28 par Bunyan
Xavier591
Xavier591
Niveau 5
27 juillet 2015 à 19:22:49

Bon alors j'ai rien dit désolé :honte:

TheRealMarco
TheRealMarco
Niveau 13
27 juillet 2015 à 20:00:44

Le 27 juillet 2015 à 19:16:38 Xavier591 a écrit :
Comment peux-tu passer en argument une fonction entre [ ] ? Il doit y avoir une erreur ...

J'ai dis juste en dessous du code, que ce que je pensais qu'il posait problème était entre crochet. Dans mon code il n'y a pas les crochets, mais je pensais que ça venait de cet endroit et je voulais qu'il soit visuellement repérable (et on ne peut pas mettre de gras dans les codes sur JVC).

Version courte : fait tes appels réseaux dans un processus séparé, quel que soit la plate-forme et le langage.

Je n'avais aucune idée de ce que c'était, et ça m'a l'air bien long à m'être en place, pour pas grand chose...

Merci beaucoup, je vais voir de ce côté alors.

Xavier591
Xavier591
Niveau 5
27 juillet 2015 à 21:28:41

Autant pour moi ! Encore désolé :hap:

TheRealMarco
TheRealMarco
Niveau 13
28 juillet 2015 à 12:37:26

Bunyan, j'ai fais le Log comme vous me l'avez dit, et c'est exactement ça. J'avais développé sur Windows Phone déjà, et il n'y avait aucunement besoin d'utiliser des Thread autre que l'UIThread.

Merci beaucoup.

Bunyan
Bunyan
Niveau 17
28 juillet 2015 à 12:42:19

De mémoire, tu en as besoin, mais c'est masqué par certains mot-clef. Un dév' Windows Phone me l'avait montré il y a deux ans, mais ne faisant pas de C# et ne développant pas pour cette plate-forme...

Bon, bref, tu as aussi une autre solution plus simple à mettre en place dans la réponse longue :)

astro788
astro788
Niveau 6
28 juillet 2015 à 19:26:44

Je ne peux que te conseiller Volley pour toutes tes requêtes HTTP :ok:

Exemple ici : http://blog.xebia.fr/2013/07/08/android-appels-reseau-avec-volley/

TheRealMarco
TheRealMarco
Niveau 13
28 juillet 2015 à 20:18:53

J'ai juste utilisé la classe héritée que j'ai trouvé ici :
https://openclassrooms.com/forum/sujet/recuperer-les-donnees-d-un-site-web-avec-android#message-84558142

C'est ce qui m'a semblé le plus simple et le plus rapide à mettre en place. C'est une toute petite appli et je n'ai pas besoin d'appeler beaucoup de site, donc c'est largement suffisant.

Merci beaucoup à vous. :ok:

DirectX11
DirectX11
Niveau 6
28 juillet 2015 à 20:33:31

Perso pour les webservice avant je codé ça a la main.. Maintenant j'utilise retrofit + okhttp

http://square.github.io/retrofit/
https://github.com/square/okhttp
http://stackoverflow.com/questions/16902716/comparison-of-android-networking-libraries-okhttp-retrofit-volley
http://i.stack.imgur.com/3u6s6.png

Message édité le 28 juillet 2015 à 20:38:30 par DirectX11
Bunyan
Bunyan
Niveau 17
29 juillet 2015 à 09:39:30

@TheRealMarco : c'est la solution indiquée dans ma version longue :p
Ce code possède deux problèmes :
- mauvaise gestion des exceptions : JAMAIS de printStackTrace sur Android
- mauvaise gestion des flux : une exception est levée et ceux-ci ne sont pas fermé (donc utilisation d'un bloc finally ou refactor pour utiliser des blocs try/finally en plus).

Pour le reste... c'est bien beau de préconiser des bibliothèques, s'il n'a besoin que d'un petit nombre d'appel (ce qui semble être le cas) et qu'il ne connaît pas trop la plate-forme (ce qui semble aussi être le cas), ce n'est pas vraiment une bonne idée à mon sens... mais bon, c'est mon habitude de "j'utilise une bibliothèque uniquement lorsque c'est nécessaire" qui ressort.

Merci pour retrofit (et son bench) que je ne connaissais pas. C'est du preprocessing d'annotation ? Si

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment