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

Flex Discussion :

UrlLoader - chargements asynchrones


Sujet :

Flex

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par défaut UrlLoader - chargements asynchrones
    Bonjour,

    Je travaille avec Flash Builder (SDK 4.5.1) et je recherche une solution (si possible native) pour charger une série de photos qui seront ensuite insérées dans un FlipBook.
    Le chargement se faisant de manière parallèle et asynchrone, dès lors qu'une image est disponible je recherche un moyen de savoir sur quelle numéro de page elle est supposée être intégrée.
    (plus simplement, lorsqu'un événement complete ou ioError survient, je cherche a connaître quel est l'écouteur dans le tableau imagesLoaders[] qui a reçu cet événement. Une fois l'index connu, je sais retrouver mon numéro de page et l'URL de l'image associée.


    Voici un exemple fonctionnel simple pour illustrer mon besoin:


    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
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    			   xmlns:s="library://ns.adobe.com/flex/spark" 
    			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
    			   creationComplete="application1_creationCompleteHandler(event)">
    	<fx:Declarations>
    		<!-- Placer ici les éléments non visuels (services et objets de valeur, par exemple). -->
    	</fx:Declarations>
     
     
    	<fx:Script>
    		<![CDATA[
    			import mx.collections.ArrayCollection;
    			import mx.events.FlexEvent;
     
     
     
     
    			protected function application1_creationCompleteHandler(event:FlexEvent):void
    			{
    				var _pictures:Array = new Array();
     
    				// collection d'instances URLLoader(s)
    				var imagesLoaders:ArrayCollection = new ArrayCollection();
     
    				/** ces images doivent s'ajouter dans un FlipBook
    				 * 
    				 *  On affecte à la page correspondante:
    				 *  > soit l'image dont le chargement vient de se terminer avec succès, 
    				 *  > sinon une image alternative locale du style aperçu non disponible
    				 * 
    				 * */
     
    				// image devant paraître en page 1
    				_pictures.push("http://www.dreuz.info/wp-content/uploads/2010/10/test.jpg");	
    				// image devant paraître en page 2
    				_pictures.push("http://www.votreopticien.com/tests_de_vue/test_2.gif");
    				_pictures.push("http://www.mac4ever.com/images/images_actu/70652_650_test_express_t_jays_four_les_intra_speciaux_iphone_ipod_de_jays.jpg");
    				_pictures.push("http://www.illustrationsof.com/royalty-free-rf-test-tube-clipart-illustration-by-cory-thoman-stock-sample-218521.jpg");
    				_pictures.push("http://www.jnack.com/inexistante1.jpg");
    				_pictures.push("http://www.jnack.com/inexistante2.jpg");	
    				_pictures.push("http://www.lesite.com/test-qi/wp-content/uploads/2010/03/test-aptitude1.jpg");
    				// image devant paraître en dernière page (8)
    				_pictures.push("http://www.jnack.com/micronaxx/wp-content/uploads/2010/02/test-pattern-clock_4767.jpg");		
     
     
     
     
    				for(var i:int=0;i<_pictures.length;i++)
    				{
    					// Test de l'image courante qui doit être inséré sur la page
    					var myUrlLoader:URLLoader = new URLLoader();
    					imagesLoaders.addItem(myUrlLoader);
     
     
    					imagesLoaders[imagesLoaders.length-1].addEventListener (Event.COMPLETE, function(event:Event):void
    					{ 
    						trace ("-----------------------------------------\nChargement OK : "+event.toString()+"\n-----------------------------------------");
    					} );
     
     
    					imagesLoaders[imagesLoaders.length-1].addEventListener (IOErrorEvent.IO_ERROR, function(event:Event):void
    					{ 
    						trace ("-----------------------------------------\n"+event.toString()+"\n-----------------------------------------");
    					} );
     
     
    					// procéder chargement de l'URL...
    					imagesLoaders[imagesLoaders.length-1].load(new URLRequest(_pictures[i]));
    				}			
     
    			}
     
    		]]>
    	</fx:Script>
     
    </s:Application>



    En exécutant ceci, j'obtiens dans la fenêtre de debug du bas les messages suivants:
    L'ordre de fin de chargement / erreur de chargement est totalement aléatoire

    -----------------------------------------
    Chargement OK : [Event type="complete" bubbles=false cancelable=false eventPhase=2]
    -----------------------------------------
    -----------------------------------------
    Chargement OK : [Event type="complete" bubbles=false cancelable=false eventPhase=2]
    -----------------------------------------
    -----------------------------------------
    Chargement OK : [Event type="complete" bubbles=false cancelable=false eventPhase=2]
    -----------------------------------------
    -----------------------------------------
    Chargement OK : [Event type="complete" bubbles=false cancelable=false eventPhase=2]
    -----------------------------------------
    -----------------------------------------
    [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Erreur de flux. URL: http://www.jnack.com/inexistante2.jpg"]
    -----------------------------------------
    -----------------------------------------
    [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Erreur de flux. URL: http://www.jnack.com/inexistante1.jpg"]
    -----------------------------------------
    -----------------------------------------
    Chargement OK : [Event type="complete" bubbles=false cancelable=false eventPhase=2]
    -----------------------------------------
    -----------------------------------------
    Chargement OK : [Event type="complete" bubbles=false cancelable=false eventPhase=2]
    -----------------------------------------

    J'ai pausé un point d'arrêt au niveau des trace(), et trouvé au travers de l'objet "event", quelques propriétés dont target et currentTarget mais rien de vraiment pertinent pour résoudre le problème.
    Faut-il ajouter quelque chose genre un token dans le tableau de loaders???

    Merci pour votre retour

  2. #2
    Membre Expert
    Avatar de Jim_Nastiq
    Homme Profil pro
    Architecte, Expert Flex
    Inscrit en
    Avril 2006
    Messages
    2 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte, Expert Flex
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 335
    Par défaut
    Salut,

    si j'ai bien compri ton problème la propriété target devrait t'aider car elle pointe vers ta référence d'image dans ton tableau.

    que te retourne dans ton handler la propriété target sur l'event de complete ?

    Pensez vraiment à effectuer une recherche avant de poster, ici et sur un moteur de recherche! c'est la moindre des choses
    Pensez au tag

    Mon Blog sur la techno Flex
    Ma page sur Developpez.com

    Jim_Nastiq

  3. #3
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Bonjour,

    Citation Envoyé par Jim_Nastiq Voir le message
    si j'ai bien compri ton problème la propriété target devrait t'aider car elle pointe vers ta référence d'image dans ton tableau.
    en fait ça pointera plus exactement vers un objet de type URLLoader. Tout irait bien si on pouvait via un getter obtenir l'URLRequest et ainsi récupérer l'url associée mais après vérif, ce n'est apparemment pas possible.

    La solution la plus simple est à mon avis de sous classer la classe URLLoader afin d'y introduire une propriété "url" par exemple et son getter associé.

    Ensuite, un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    var url:String = SousClasseURLLoader(event.target).url;
    devrait faire l'affaire.

    A ce que je comprends, ton tableau _pictures te sert à faire une sorte de lookup afin de récupérer l'indice puis l'url associée. SI tel est le cas, tu n'as plus besoin de tableau maintenant.

    2 remarques complémentaires aussi :

    1. Si tu sais ce que tu vas mettre dans un tableau ce qui est le cas ici (une série d'url donc de String), utilise la classe Vector plutôt qu'array. Les performances seront théoriquement 20X meilleures (c'est négligeable ici mais autant prendre les bonnes habitudes ). De plus ensuite plus besoin de caster en String ou autres classes, c'est automatiquement fait (c'est ce qu'on appelle le "type safe" en anglais).

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
       
      var urls:Vector.<String> = new Vector.<String>;
      urls.push(...);
      urls.push(...);
      ...
       
      // plus besoin ici de caster avec String()
      trace(urls[0].charAt(0));
    2. Evite les fonctions anonymes dans les écouteurs ou bien défini le paramètre "useWeakReference" à true afin de ne pas créer de fuites de mémoire. Le mieux étant à mon avis de gérer une fonction à part et de supprimer toi même les références de l'objet vers les écouteurs avec removeEventListener.



    Bon dév'

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par défaut
    Salut Jim_Nastiq,

    Sur un événement Complete,

    event.target = flash.net.URLLoader (@11f542ac1)



    Sur un événement IOError,

    event.target = flash.net.URLLoader (@11e3b3741)
    event.target.data =

    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html><head>
    <title>404 Not Found</title>
    </head><body>
    <h1>Not Found</h1>
    <p>The requested URL /inexistante1.jpg was not found on this server.</p>
    <hr>
    <address>Apache/2.0.54 Server at www.jnack.com Port 80</address>
    </body></html>

  5. #5
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Bonjour,

    as tu regardé mon message c'est ce que j'ai écris plus haut :

    Citation Envoyé par Madfrix Voir le message
    en fait ça pointera plus exactement vers un objet de type URLLoader.
    Il ne semble pas possible de récupérer l'URLRequest pour obtenir l'url associée via URLLoader, c'est pour ca que je te propose de sous classer cette classe :

    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
     
    public class MyCustomURLLoader extends URLLoader
    {
    	private var _url:String;
     
    	public function MyCustomURLLoader(request:URLRequest=null)
    	{
    		super(request);
                   _url = request.url;
    	}
     
    	public function get url():String
    	{
    		return _url;
    	}
     
    }
    Ensuite, le code est simple :

    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
     
    private var customURLLoader:MyCustomURLLoader;
    private var urlRequest:URLRequest;
     
    protected function application1_creationCompleteHandler(event:FlexEvent):void
    {
       var urls:Vector.<String> = new Vector.<String>;
       urls.push("http://www.dreuz.info/wp-content/uploads/2010/10/test.jpg");
       urls.push("http://www.votreopticien.com/tests_de_vue/test_2.gif");
       urls.push("http://www.mac4ever.com/images/images_actu/70652_650_test_express_t_jays_four_les_intra_speciaux_iphone_ipod_de_jays.jpg");
       urls.push("http://www.illustrationsof.com/royalty-free-rf-test-tube-clipart-illustration-by-cory-thoman-stock-sample-218521.jpg");
       urls.push("http://www.jnack.com/inexistante1.jpg");
       urls.push("http://www.jnack.com/inexistante2.jpg");
       urls.push("http://www.lesite.com/test-qi/wp-content/uploads/2010/03/test-aptitude1.jpg");
       urls.push("http://www.jnack.com/micronaxx/wp-content/uploads/2010/02/test-pattern-clock_4767.jpg");
     
     
       for each(var url:String in urls)
       {
          urlRequest = new URLRequest(url);
          customURLLoader = new MyCustomURLLoader(urlRequest);
          customURLLoader.addEventListener(Event.COMPLETE, onComplete);
          customURLLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
       }
    }
     
       private function onComplete(e:Event):void
       {
          var target:MyCustomURLLoader = MyCustomURLLoader(e.target);
          trace("chargé : " + target.url);
          target.removeEventListener(Event.COMPLETE, onComplete); 	  
          target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);			
       }
     
       private function onIOError(e:IOErrorEvent):void
       {
          var target:MyCustomURLLoader = MyCustomURLLoader(e.target);
          trace("erreur : " + target.url); 
          target.removeEventListener(Event.COMPLETE, onComplete);
          target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
       }
    Chez moi, cela donne :


  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par défaut
    Bonjour Madfrix,

    J'ai bien consulté ta réponse ce matin et effectué les changements suivants dans le code:

    Création de la sous classe suivante, dérivée de UrlLoader:

    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
    package
    {
    	import flash.net.URLLoader;
     
    	public class CMyUrlLoader extends URLLoader
    	{
    		private var _resourceNo:int;
    		private var _resourceUrl:String;	
     
    		public function CMyUrlLoader()
    		{	
    			_resourceNo = 0;
    			_resourceUrl = "";
    		}
     
     
    		public function set resourceIdx(tmpNo:int):void		{
    			_resourceNo = tmpNo;
    		}
     
    		public function get resourceIdx():int		{
    			return _resourceNo;
    		}		
     
    		public function set resourceURL(tmpUrl:String):void		{
    			_resourceUrl = tmpUrl;
    		}
     
    		public function get resourceURL():String		{
    			return _resourceUrl;
    		}
     
    	}
    }


    Utilisation de cette sous classe:



    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
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    			   xmlns:s="library://ns.adobe.com/flex/spark" 
    			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
    			   creationComplete="application1_creationCompleteHandler(event)">
    	<fx:Declarations>
    		<!-- Placer ici les éléments non visuels (services et objets de valeur, par exemple). -->
    	</fx:Declarations>
     
     
    	<fx:Script>
    		<![CDATA[
    			import mx.collections.ArrayCollection;
    			import mx.events.FlexEvent;
    			import mx.messaging.messages.IMessage;
    			import mx.rpc.AsyncToken;
     
     
     
     
     
     
    			protected function application1_creationCompleteHandler(event:FlexEvent):void
    			{
    				var _pictures:Array = new Array();
     
    				// collection d'instances URLLoader(s)
    				var imagesLoaders:ArrayCollection = new ArrayCollection();
     
    				/** ces images doivent s'ajouter dans un FlipBook
    				 * 
    				 *  On affecte à la page correspondante:
    				 *  > soit l'image dont le chargement vient de se terminer avec succès, 
    				 *  > sinon une image alternative locale du style aperçu non disponible
    				 * 
    				 * */
     
    				// image devant paraître en page 1
    				_pictures.push("http://www.dreuz.info/wp-content/uploads/2010/10/test.jpg");	
    				// image devant paraître en page 2
    				_pictures.push("http://www.votreopticien.com/tests_de_vue/test_2.gif");
    				_pictures.push("http://www.mac4ever.com/images/images_actu/70652_650_test_express_t_jays_four_les_intra_speciaux_iphone_ipod_de_jays.jpg");
    				_pictures.push("http://www.illustrationsof.com/royalty-free-rf-test-tube-clipart-illustration-by-cory-thoman-stock-sample-218521.jpg");
    				_pictures.push("http://www.jnack.com/inexistante1.jpg");
    				_pictures.push("http://www.jnack.com/inexistante2.jpg");	
    				_pictures.push("http://www.lesite.com/test-qi/wp-content/uploads/2010/03/test-aptitude1.jpg");
    				// image devant paraître en dernière page (8)
    				_pictures.push("http://www.jnack.com/micronaxx/wp-content/uploads/2010/02/test-pattern-clock_4767.jpg");		
     
     
     
     
    				for(var page:int=0;page<_pictures.length;page++)
    				{
    					// Test de l'image courante qui doit être inséré sur la page
    					var myUrlLoader:CMyUrlLoader = new CMyUrlLoader();
     
    					// register the image ressource URL attribute, because  UrlLoader base class doesn't handle it automaticaly
    					myUrlLoader.resourceIdx	= page;
    					myUrlLoader.resourceURL	= _pictures[page];
     
    					imagesLoaders.addItem(myUrlLoader);
     
     
    					imagesLoaders[imagesLoaders.length-1].addEventListener (Event.COMPLETE, function(event:Event):void
    					{ 
    						var pageNo:int 			= int (event.target.resourceIdx) + 1;
    						var contentUrl:String	= event.target.resourceURL;
     
    						trace ("-----------------------------------------\nChargement page "+pageNo.toString()+"\t\t OK! > "+contentUrl);
    					} );
     
     
    					imagesLoaders[imagesLoaders.length-1].addEventListener (IOErrorEvent.IO_ERROR, function(event:Event):void
    					{ 
    						var pageNo:int 			= int (event.target.resourceIdx) + 1;
    						var contentUrl:String	= event.target.resourceURL;
     
    						trace ("-----------------------------------------\nChargement page "+pageNo.toString()+"\t\t Erreur! > "+contentUrl);
    					} );
     
     
    					// procéder chargement de l'URL...
    					imagesLoaders[imagesLoaders.length-1].load(new URLRequest(_pictures[page]));
    				}			
     
    			}
     
    		]]>
    	</fx:Script>
     
    </s:Application>


    Ce qui me donne à l'exécution:

    -----------------------------------------
    Chargement page 1 OK! > http://www.dreuz.info/wp-content/upl...10/10/test.jpg
    -----------------------------------------
    Chargement page 2 OK! > http://www.votreopticien.com/tests_de_vue/test_2.gif
    -----------------------------------------
    Chargement page 4 OK! > http://www.illustrationsof.com/royal...ple-218521.jpg
    -----------------------------------------
    Chargement page 8 OK! > http://www.jnack.com/micronaxx/wp-co...clock_4767.jpg
    -----------------------------------------
    Chargement page 7 OK! > http://www.lesite.com/test-qi/wp-con...-aptitude1.jpg
    -----------------------------------------
    Chargement page 3 OK! > http://www.mac4ever.com/images/image...od_de_jays.jpg
    -----------------------------------------
    Chargement page 5 Erreur! > http://www.jnack.com/inexistante1.jpg
    -----------------------------------------
    Chargement page 6 Erreur! > http://www.jnack.com/inexistante2.jpg


    Remarques:

    - Je n'ai pas encore intégré la notion des vecteurs dans la solution, ce que je vais faire cet après midi.
    - Cela semble fonctionner correctement, mais je ne sais pas si ma sous classe est dérivée correctement, car je n'ai pas employé la "l'instruction" super(...). Je vais retravailler tout ça pour mieux tirer avantage des possibilités offertes pas ce langage.


    En tous cas, merci beaucoup pour votre aide à tous les deux.
    Madfrix, je vais examiner de plus près ton code

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

Discussions similaires

  1. Chargement asynchrone dans une listView
    Par Invité dans le forum C#
    Réponses: 9
    Dernier message: 25/07/2013, 17h34
  2. Problème MVVM et chargements asynchrones
    Par jeanjean40 dans le forum Silverlight
    Réponses: 4
    Dernier message: 30/12/2011, 10h53
  3. Jquery Mobile: chargement asynchrone
    Par Soull dans le forum jQuery
    Réponses: 0
    Dernier message: 13/04/2011, 15h57
  4. Chargement asynchrone d'images d'une liste.
    Par Cuillere dans le forum Android
    Réponses: 2
    Dernier message: 23/07/2010, 15h25
  5. Chargement Asynchrone d'image dans une liste
    Par Invité dans le forum Android
    Réponses: 4
    Dernier message: 10/05/2010, 16h48

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