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 :

Comment éviter NetworkOnMainThreadException


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2013
    Messages : 7
    Par défaut Comment éviter NetworkOnMainThreadException
    Bonjour à tous,
    Je n'arrive pas à me dépétrer de cette erreur NetworkOnMainThreadException. Biensur, je sais qu'il ne faut pas faire du Network depuis le mainThread. J'ai mis mon code de test dans un Thread, et cela fonctionne.

    Mais en fait je dois communiquer avec une api SOAP web, et donc effectuer plusieurs requêtes à la suite, et ce, de façons conditionnelles. Ex :

    if (! identified) {
    .. httpRequest1 : login
    } else {
    .. if (currentDB == "toto") {
    .... httpRequest 2;
    .... httpRequest 3;
    }

    donc si je commence a jouer avec des Handler et des Runnables, je vais en faire pleins... c'est pourri !

    Je ne vois pas comment faire...

    Pouvez-vous m'aider ?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    757
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 757
    Par défaut
    Une solution simple est d'utiliser les AsyncTask.
    Elles séparent bien les tâches à effectuer dans le UiThread et celles à faire en arrière plan.

    La méthode doInBackground comme son nom l'indique, est l'endroit où tu peux faire tes requêtes web.
    Et onPostExecute te permet de modifier et d'intérragir avec le Thread graphique lorsque ta tâche est finie.

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2013
    Messages : 7
    Par défaut Toujours pas
    Merci pour ta réponse rapide. J'ai essayé sans succès :
    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
    		tv = (TextView) findViewById(R.id.textView1);
    		button = (Button) findViewById(R.id.button1);
    		button.setOnClickListener(new View.OnClickListener() {
    			public void onClick(View v) {
    				class Sess extends AsyncTask<Void, Integer, Long> {
    					protected Long doInBackground(Void... arg0) {
    						linkSession.isSessionOpened();
    						linkSession.executeBatch(false, null, null);
    						return null;
    					}
     
    					protected void onPostExecute(Long result) {
    						tv.setText(linkSession.getSoapResponse());
    					}
    				}
    				new Sess().execute();
    			}
    		});
    Mon isSessionOpened construit simplement la requête SOAP dans un String.
    Mon executeBatch effectue le post HTTP de la requête sur le serveur, c'est à ce moment que çà plante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    06-11 14:16:40.035: E/AndroidRuntime(2189): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

    C'est pas très propre, désolé, pour le moment je valide le process avant de faire propre.

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    757
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 757
    Par défaut
    En effet, ce n'est pas propre, et ça te fait faire des erreurs
    La classe devrait être définie à l'exterieur du onClick.

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2013
    Messages : 7
    Par défaut
    Oui, mais j'ai beau la sortir du onClick... ça plante toujours :

    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
    public class MainTestSOAP extends Activity {
    	private TextView tv;
    	private Button button;
    	private TLinkSession linkSession = new TLinkSession();
     
    	class Sess extends AsyncTask<Void, Integer, Long> {
    		protected Long doInBackground(Void... arg0) {
    //			Looper.prepare();
    			linkSession.isSessionOpened();
    			linkSession.executeBatch(false, null, null);
    			return null;
    		}
     
    		protected void onPostExecute(Long result) {
    			tv.setText(linkSession.getSoapResponse());
    		}
    	}
     
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main_test_soap);
     
    		tv = (TextView) findViewById(R.id.textView1);
    		button = (Button) findViewById(R.id.button1);
    		button.setOnClickListener(new View.OnClickListener() {
    			public void onClick(View v) {
    				new Sess().execute();
    			}
    		});
    	}
    }
    J'ai tenté de mettre le Looper.prepare(); mais je ne vois pas pourquoi ni comment cela fonctionne...

  6. #6
    Expert confirmé

    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
    Billets dans le blog
    3
    Par défaut
    Non non le Looper.prepare() permet de créer une pile de message, chose que le thread UI a déjà.

    Là on dirait que le onClick() est reçu dans un autre thread que celui de l'UI, ce qui est très étrange !

    On peut avoir la stacktrace complète ? (et pas seulement l'exception) ?

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

Discussions similaires

  1. Comment éviter le lancement automatique de CBuilder
    Par Xavier dans le forum C++Builder
    Réponses: 3
    Dernier message: 26/01/2005, 17h35
  2. Comment éviter les doublons dans ma table
    Par einegel dans le forum Bases de données
    Réponses: 3
    Dernier message: 09/11/2004, 12h18
  3. [TEdit] Comment éviter le bip ?
    Par portu dans le forum Composants VCL
    Réponses: 4
    Dernier message: 01/10/2004, 12h01
  4. Réponses: 4
    Dernier message: 28/07/2004, 10h42
  5. [eclipse 2.1][compilation] Comment éviter...
    Par ftrifiro dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 29/06/2004, 16h16

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