Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > dimarik

Оценить эту запись

Loader можно использовать повторно

Запись от dimarik размещена 22.06.2010 в 01:16
Обновил(-а) dimarik 22.06.2010 в 01:39

А все ли знают, что единожды инстанцированный экземпляр класса Loader можно использовать повторно сколь угодно раз для скачивания очередной картинки или флеш-ролика? Теперь знаете. Его можно использовать для загрузки сколь угодно многих SWF. И я не оговорился. Те картинки, что в форматах JPG, PNG, GIF преобразуются нашим умным флеш-плеером именно в формат SWF. Но это отдельная история о 85-ом теге и я, может быть, немного расскажу о ней. В другой раз.

А сейчас нас интересует повторное использование объекта типа Loader.

Немного простого кода.

Код AS3:
var loader:Loader = new Loader();
this.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.handler_complete);
this.handler_complete(null);
 
 
function loadNext(request:URLRequest):void {
    this.loader.load(request);
}
 
function handler_complete(event:Event):void {
    if (event)
        super.addChild( (event.target as LoaderInfo).content ); // Картинка или swf уже в нас )
    if ( /* пока условие */) // Давай следующую
        this.loadNext( new URLRequest(/* some url request here */) )
}
Наш простой пример служит для общего понимания следующей забавной фишки - использования чужого лоадера, а значит, продолжение следует...
Всего комментариев 38

Комментарии

Старый 22.06.2010 09:50 Juice_Green вне форума
Juice_Green
 
Аватар для Juice_Green
интересно!
я вот сегодня набрел на LoaderMax от greensock'a. Может тоже будет интересно им кому попользоваться.
Старый 22.06.2010 11:16 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
А что такое 85-й тег?
Старый 22.06.2010 11:25 dimarik вне форума
dimarik
 
Аватар для dimarik
Недокументированный тег структуры SWF-файла.
Старый 22.06.2010 21:10 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Забавно. А я плодил кучи лоадеров.
Интересно, откуда пошло что на одну загрузку один лоадер?
Наверное, добавляли в дисплай лист сам лоадер.
Старый 22.06.2010 21:24 Котяра вне форума
Котяра
 
Аватар для Котяра
Практически всегда использовал один лоадер для загрузки по списку.. даже и не думал что это багофича.
Старый 22.06.2010 21:33 Division вне форума
Division
 
Аватар для Division
А вот у меня при использовании одного лоадера были некоторые проблемы: http://www.flasher.ru/forum/showthread.php?t=133621
Старый 22.06.2010 21:56 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Смешно, но я попал в самую точку
http://www.flasher.ru/forum/showthread.php?t=141359
Старый 22.06.2010 22:22 Nirth вне форума
Nirth
 
Аватар для Nirth
кто то плодил Loader'ы вне прототипов приложений?
Старый 22.06.2010 23:48 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Nirth, объясни.
Старый 22.06.2010 23:55 silin вне форума
silin
 
Аватар для silin
интрига, однако: 85-й тег, использования чужого лоадера..
а в чем прикол не догнать - ну грузит лоадер, так какбе всегда так и было ?
Старый 23.06.2010 02:41 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Проблема в том, что если добавить загруженого ребенка не лоадеру, а другому контейнеру, то потом его уже никак не выгрузить. Ну а если это картинка, то, конечно, почему бы и не использовать один лоадер? скопировал битмапдату, ее и сохранил, а сам файл выгрузил, вроде как все так и делают...
Старый 23.06.2010 08:12 Nirth вне форума
Nirth
 
Аватар для Nirth
Цитата:
Nirth, объясни.
объяснить что?
Старый 23.06.2010 10:57 dimarik вне форума
dimarik
 
Аватар для dimarik
Котяра, ты молодец. Однако Флешер читают и подрастающие девелоперы. Это может показаться полезным.

Олег, нет такой проблемы. Если загружается swf, то критерием того, что произойдет полная выгрузка является:

a) отсутствие ссылок на ApplicationDomain, в котором находятся загруженные Definitions (классы, интерфейсы, функции)

б) Отсутствие ссылок на инстанцированные объекты этих типов.

Под полной выгрузкой я понимаю, что в окне output FlexBuildera появится текст "[Unload SWF...]"

Плодить лоадеры тоже нужно. Если происходит массовая загрузка, полезно иметь 3-5(?) лоадеров, работающих параллельно. Таким образом множество мелких изображений, например, можно грузить быстрее. Многие соцсети порталы специально располагают контент на многочисленных доменах третьего уровня, обходя таким образом ограничения браузера на максимальное количество соединений с одним хостом. Грех этим не воспользоваться.

А интрига должна быть )
Обновил(-а) dimarik 23.06.2010 в 11:01
Старый 23.06.2010 13:18 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Загрузи подряд две SWF в один лоадер не выгружая первую до того, как загрузишь вторую. Т.е. добавь ее куда-нибудь к другому контейнеру, а потом попробуй выгрузить.
Старый 23.06.2010 13:57 dimarik вне форума
dimarik
 
Аватар для dimarik
Прекрасно выгружает. FP 10.1.53 и 10.0.22.
Старый 23.06.2010 16:29 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Цитата:
кто то плодил Loader'ы вне прототипов приложений?
Вот это )
Что ты этим хотел сказать?
Старый 23.06.2010 18:21 Nirth вне форума
Nirth
 
Аватар для Nirth
Я не понимаю, что тебе не понятно )
Мне казалось, что не считая прототипов приложений, лоадеры реюзают.
Старый 23.06.2010 19:07 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Цитата:
Прекрасно выгружает. FP 10.1.53 и 10.0.22.
Я давно не пробовал, но так смутно помню, что при попытке выгрузить давалась ошибка типа "объект не является ребенком контейнера", и имелось в виду то, что лоадер хотел удалить ребенка в то время как не являлся его родителем.
Старый 23.06.2010 20:14 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Ну хорошо, может я просто тебя не понимаю в терминологии)
Что есть прототип приложения?
Старый 23.06.2010 20:55 Nirth вне форума
Nirth
 
Аватар для Nirth
Демка, Макет, Пример
Старый 23.06.2010 21:34 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Ну понимаю я тебя правильно.
Я поразмыслил - ты имеешь ввиду что при переходе приложения в релизную стадию лоадеры сжимаются от много до единиц?
Старый 23.06.2010 21:37 dimarik вне форума
dimarik
 
Аватар для dimarik
Олег, не будешь ли ты так любезен объяснять, что скрывается за твоими фразами? Например, здесь
Цитата:
что при попытке выгрузить
какой код стоит за этой сентенцией?


Браво, Тигра! Так их! Пускай тоже шевелятся и рассказывают.
Обновил(-а) dimarik 23.06.2010 в 21:42
Старый 23.06.2010 21:38 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
myLoader.unload()
Старый 23.06.2010 21:52 dimarik вне форума
dimarik
 
Аватар для dimarik
Понятно. У меня нет такой строчки.
Старый 23.06.2010 22:03 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
dimarik, я не понимаю иронии.
Мои лоадеры уходят в null как только выполнят свою задачу, потом создаются новые. По сути, я немного теряю при создании-удалении, однако если я ничего не гружу - у меня не висит лоадер в памяти. Или я совсем не о том?
Старый 23.06.2010 22:52 dimarik вне форума
dimarik
 
Аватар для dimarik
Интрига, только интрига. Чужие лоадеры ожидают нас.
Старый 23.06.2010 23:40 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Димарик, ты бы лучше рассказал мне что по твоему мнению не совсем хорошо, быть может я допускаю большую ошибку =)
Да и диалог как то в монолог перерастает, не есть приятно.
Старый 24.06.2010 00:34 dimarik вне форума
dimarik
 
Аватар для dimarik
Тигра, прошу прощения за то, что тебе так показалось. Не всегда "хорошо" может быть однозначно. Что по мне, то единственную цель этой статьи я раскрыл - Loader может быть использован повторно. Следующая статья уже написана. Еще одна готовится. Она про "чужие" лоадеры и проблемы безопасности куда более существенные. Так что наберись терпения.

Подвис над названием будущей статьи. Как считаешь, "Loader vs. FP security. Белые начинают и выигрывают." будет сильно вычурным? Нет, назову, пожалуй, так: "Loader vs FP security. Мат в два хода." Мне кажется, это будет соответствовать содержанию. xD
Обновил(-а) dimarik 24.06.2010 в 01:29
Старый 24.06.2010 12:50 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Я не знаю о чем она, поэтому не могу сказать какое название лучше )
Старый 24.06.2010 12:55 dimarik вне форума
dimarik
 
Аватар для dimarik
Старый 25.06.2010 23:25 dixlofos вне форума
dixlofos
 
Аватар для dixlofos
а unload() чем не мил?

Код AS3:
package
{
	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.events.*;
 
	public class Main extends Sprite
	{		
		private var img;
		private var loader:Loader;
 
		public function Main():void
		{
			loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, cf);
			loader.load(new URLRequest("img1.jpg"));
		}
 
		private function cf(e:Event):void
		{
			img = e.target.content;
			addChild(img);
			img.x=Math.random()*100;
			img.y = Math.random()*100;
			loader.unload();
			loader.load(new URLRequest("img2.jpg"));															  
		}
	}
}
всё работаит. Имхо, идеальный вариант, если нам не нужно потом двигать объекты на прямую, для управления х y можно добавить еще одну перемнную и на основе её управлять
Старый 26.06.2010 00:24 dimarik вне форума
dimarik
 
Аватар для dimarik
Цитата:
а unload() чем не мил?
Вы уверены, что правильно поняли статью и комментарии к ней?
Обновил(-а) dimarik 26.06.2010 в 03:24
Старый 27.06.2010 00:00 dixlofos вне форума
dixlofos
 
Аватар для dixlofos
dimarik
Эта статья про то как использовать лоадер повторно? Или я что-то недопонял?)
Старый 05.01.2011 00:35 tsarapkabel вне форума
tsarapkabel
 
Аватар для tsarapkabel
Не совсем понял код dimarik'а, можно привести более конкретный пример многократного использования loader'а? Допустим для трёх картинок.
Старый 05.01.2011 05:21 TanaTiX вне форума
TanaTiX
 
Аватар для TanaTiX
Как я понимаю обычная рекурсия.
Старый 05.01.2011 13:36 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
@tsarapkabel, например вот.
Мой старый, но что странно, работающий класс:
Код AS3:
package artshlagin.loaders 
{
	import artshlagin.events.MultiLoaderEvent;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	import flash.utils.ByteArray;
 
	/**
	 * ...
	 * @author Artem Shlagin
	 */
	public class MultiDisplayObjectLoader extends EventDispatcher
	{
		private var _totalImages:int;
		private var _currentLoading:int;
		private var _loadList:Array;
		private var _loader:Loader;	
		private var _loadedDisplayObjects:Array;
		private var _isLoading:Boolean;
 
		public var antiCacheEnabled:Boolean;
		[Event(name="allLoaded", type="artshlagin.events.MultiLoaderEvent")]
		[Event(name = "imageLoaded", type = "artshlagin.events.MultiLoaderEvent")]
		[Event(name = "loadingDropped", type = "artshlagin.events.MultiLoaderEvent")]
		[Event(name = "loadStarted", type = "artshlagin.events.MultiLoaderEvent")]
		[Event(name = "taskChanged", type = "artshlagin.events.MultiLoaderEvent")]
 
		public function MultiDisplayObjectLoader(loadList:Array = null) 
		{
			super(null);
			antiCacheEnabled = true;
			_loadList = [];
			_loader = new Loader();
			_isLoading = false;
			_currentLoading = -1;
			if (loadList) load(loadList);
		}
 
		public function load(loadList:Array):void
		{
			var i:int = loadList.length;
			while (i--) {
				if (!loadList[i]) throw new ArgumentError("loadList contains null reference");
			}
			_isLoading = true;
			if (!_loadList.length) {
				//no queue -> new load
				_currentLoading = 0;
				_totalImages = 0;
				_loadedDisplayObjects = [];
				_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadingComplete);
				_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
				_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, super.dispatchEvent);
			}
			_loadList = _loadList.concat(loadList);
			_totalImages = _totalImages + loadList.length;
			super.dispatchEvent(new MultiLoaderEvent(MultiLoaderEvent.TASK_CHANGED));
 
			if (!_currentLoading) loadNext(); //если ещё ничего не грузим - начнем
		}
 
 
 
		private function onLoadingComplete(e:Event):void 
		{
			_loadedDisplayObjects.push(_loader.content);
			super.dispatchEvent(new MultiLoaderEvent(MultiLoaderEvent.IMAGE_LOADED));
			if (!_loadList.length) {
				//nothing to load
				_isLoading = false;
				_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadingComplete);
				_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
				_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, super.dispatchEvent);
				super.dispatchEvent(new MultiLoaderEvent(MultiLoaderEvent.ALL_LOADED));
				return;
			}
 
			_currentLoading++;
			loadNext();
		}
 
		private function onIOError(e:IOErrorEvent):void 
		{
			_isLoading = false;
			_loadList = [];
			_totalImages = _currentLoading;
			_currentLoading = -1;
			super.dispatchEvent(e);
		}
 
		private function loadNext():void
		{
			super.dispatchEvent(new MultiLoaderEvent(MultiLoaderEvent.LOAD_STARTED));
			//strings or URLRequest or ByteArray
			var obj:*= _loadList.shift();
			if (obj is ByteArray) {
				_loader.loadBytes(obj);
				return;
			}
			var request:URLRequest;
			if ((typeof obj) == "string") request = new URLRequest(obj+ (antiCacheEnabled ? "?"+(Math.random().toString().split(".").join("")) : "" ));
			else if ((typeof obj) == "object") request = obj as URLRequest;
			else throw new ArgumentError("The loadList argument must contain only strings, URLRequest`s or ByteArrays");
 
			_loader.load(request);
		}
 
		/**
		 * Получить тот DisplayObject, что загрузили
		 * @param	id 	Номер DisplayObject`а, который нужно получить. Новые имеют больший id
		 *  	 	 	при id = -1 возвращает самую последнюю загруженную картинку
		 * @return
		 */
		public function getDisplayObject(id:int = -1):DisplayObject {
			if (id == -1) return _loadedDisplayObjects[_loadedDisplayObjects.length - 1];
			if (id < 0 || id >= _loadedDisplayObjects.length) throw new ArgumentError("Out of bounds with id " + id);
			return _loadedDisplayObjects[id];
		}
 
		/**
		 * Возвращает массив всех загруженных DisplayObject`ов
		 * @return
		 */
		public function getAllDisplayObjects():Array {
			return _loadedDisplayObjects.slice();
		}
 
		/**
		 * Прекращает закачку
		 */
		public function drop():void {
			if (!_isLoading) return;
			_loader.close();
			_isLoading = false;
			_loadList = [];
			_totalImages = _currentLoading;
			_currentLoading = -1;
			super.dispatchEvent(new MultiLoaderEvent(MultiLoaderEvent.DROP));
		}
 
		public function get totalImages():int { return _totalImages; }
 
		public function get currentLoading():int { return _currentLoading; }
 
		public function get isLoading():Boolean { return _isLoading; }
 
	}
 
}
Код AS3:
package artshlagin.events 
{
	import flash.events.Event;
 
	/**
	 * ...
	 * @author Artem Shlagin
	 */
	public class MultiLoaderEvent extends Event 
	{
 
		public static const ALL_LOADED:String = "allLoaded";
		public static const IMAGE_LOADED:String = "imageLoaded";
		public static const DROP:String = "loadingDropped";
		public static const LOAD_STARTED:String = "loadStarted";
		public static const TASK_CHANGED:String = "taskChanged";
 
 
		public function MultiLoaderEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) 
		{ 
			super(type, bubbles, cancelable);
 
		} 
 
		public override function clone():Event 
		{ 
			return new MultiLoaderEvent(type, bubbles, cancelable);
		} 
 
		public override function toString():String 
		{ 
			return formatToString("MultiLoaderEvent", "type", "bubbles", "cancelable", "eventPhase"); 
		}
 
	}
 
}
Старый 06.01.2011 05:20 tsarapkabel вне форума
tsarapkabel
 
Аватар для tsarapkabel
Спасибо, Артём, но 200 строк кода для меня не простой пример повторного использования loader'а.
Полвечера ковырял, но так до конца и не понял, как неправильно использовать твой класс.

А пример я имел ввиду такой (эт я преобразовал код dimarik'а):
Код AS3:
package {
 
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;
 
	[SWF (width=800, height=600, backgroundColor = 0xCCCCCC)]
 
 
	/*
		@author soniko
	*/
 
	public class PictureLoader extends Sprite {
 
		private var loadList:Array;
		private var ldr:Loader;
 
 
		public function PictureLoader():void {
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
 
		private function init(e:Event = null):void {
			ldr = new Loader();
			loadList = new Array ("1.jpg", "2.jpg", "3.jpg");
			ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
			loadComplete(null);
		}
 
		private function loadComplete(event:Event):void {
			if (event) {
				super.addChild((event.target as LoaderInfo).content);
				loadList.shift();
			}
			if (loadList.length > 0) {
				loadNext(new URLRequest(loadList[0]));
			}
		}
 
		private function loadNext (request:URLRequest):void {
			ldr.load(request);
		}
	}	
}
Старый 06.01.2011 16:20 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Цитата:
Полвечера ковырял, но так до конца и не понял, как неправильно использовать твой класс.
Его неправильно использовать и нельзя
Использовать как-то так: создать экземпляр, вызвать метод load, в который передать массив String/URLRequest, подписаться на событие какое-нибудь (например, IMAGE_LOADED) и тащить в обработчике свежий DisplayObject, например через метод getDisplayObject().
Вообще класс - велосипед, тот же bulkloader покруче будет. Дал с целью показать что имел ввиду dimarik. Рад, что ты разобрался
 

 


Часовой пояс GMT +4, время: 22:44.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.