Я уже писал, как использовать ant-скрипты для сердитой компиляции флэш-проектов, чтобы тестировать обновленный(е) скомпилированный(е) swf-файл(ы) сразу в окне браузера, содержащем открытый прямо с вашего сервера документ, а не в одиного торчащем окне standalone-flash-проигрывателя.
Сегодня мы рассмотрим, как, базируясь на том же самом билд-скрипте, передать вашему флэш-приложению дополнительные параметры через адресную строку браузера (иными словами, передать параметры через GET-запрос). Один из самых распространненых случаев, когда нам нужен это прием -- это так называемый запрет кэширования swf-файла(ов). Как вы наверняка уже знаете, чтобы загружаемый файл гарантированно обновился, а не брался из кэша браузера, существует верный способ: изменять путь к нему, приписывая к этому пути параметр с изменяющимся значением. В результате html-код будет выглядеть как: <param name="movie" value="app.swf?v=1.0.121">. В качестве изменяющегося параметра мы будем приписывать номер билда, увеличивающийся на единицу при каждой компиляции проекта. Его еще называют минорной версией и стандартно изпользуют как в Java, так и в .NET.
<param name="movie" value="app.swf?v=1.0.121">
Итак, разберемся, что нам нужно получить. Начинаем "с конца":
Всего три шага к решению задачи! Из них первый не требует никаких усилий вообще. Второй шаг тоже несложный, но нужно акцентировать внимание не том, как именно мы возьмем значение параметра из адресной строки и передадим его флэш-объекту. Для этого лучше всего подходит SWFObject, так как у него уже есть встроенный и тыщу раз протестированный метод getQueryParamValue(), который берет аргументы адресной строки браузера и приписывает их как параметры swf-объекта прямо в исходный код: so.addVariable("v", getQueryParamValue("v")); so.write("flashcontent"); этим мы и воспользуемся!
getQueryParamValue()
so.addVariable("v", getQueryParamValue("v")); so.write("flashcontent");
Кстати, если вы до сих пор не используете SWFObject для встраивания флэш-приложений в свои страницы, то вам стоит начать это делать прямо сейчас, благо есть понятная и компактная русскоязычная инструкция к SWFObject от МК. Вообще, без SWFObject лучше ничего дальше не делайте, потому что он и проблемы отображения Flash в IE решает (помните историю с Eolas-патентом, из-за которой мы до сих пор выгребаем?), и версию проигрывателя может легко определить. К поисковикам он тоже дружелюбнее всех остальных способов встраивания флэша в веб-страницу. При этом он прост и элегантен! В общем, если ваши лыжи при скольжении по асфальту до сих пор издают неприятный звук, переходите на использование SWFObject как можно скорее!
Третий шаг производится в билд-файле. Для увеличения номера билда в ant имеется спецсвойство <buildnumber />. Оно принимает аргумент "file" (по умолчанию он равен "build.number")—имя файла, в котором будет храниться номер билда. Если такого файла нет, он будет создан в корневом каталоге проекта. Если уже есть—то хранящийся в нем номер билда увеличивается на единицу (также в этом файле хранится дата/время последнего билда).
<buildnumber />
file
build.number
Используем же свойство <buildnumber /> в билд-файле из предыдущего урока, посвященного сердитой компиляции! Для этого добавим в него новую цель "build.number.increment" и обеспечим ее вызов из основной цели "build" прежде двух других целей, "mtasc.compile" и "run.html". И, наконец, в цели run.html припишем увеличенное значение из build.number к аргументу output.html,—обратите внимание, ради этого последнего действия все и затевалось: <arg line="${output.html}${build.number}" />.
build.number.increment
build
mtasc.compile
run.html
output.html
<arg line="${output.html}${build.number}" />.
Заметьте, как выглядит теперь аргумент output.html: он заканчивается строкой "/index.html?v=0.0."—таким образом, после приписывания к нему номера билда получится нечто вроде "/index.html?v=0.0.121"—и последнее число будет автоматически увеличиваться с каждой компиляцией и попадать в адресную строку браузера. А Javascript из страницы index.html будет брать этот аргумент из адресной строки и приписывать его к параметру movie swf-файла, и мы получим требуемый: <param name="movie" value="app.swf?v=1.0.121">. Кстати, флэш-приложение app.swf может затем использовать этот параметр во всех своих методах загрузки внешних данных, таким образом исключая кеширование и их тоже!
/index.html?v=0.0.
/index.html?v=0.0.121
movie
Вот обновленный код файла build.xml (новые строки выделены жирным):
<?xml version="1.0"?> <project default="build" basedir="."> <property name="mtasc.path" value="C:\Program Files\Mtasc\mtasc.exe" /> <property name="matsc.args" value='App -version 8 -swf "d:\projects\[PROJECT]\bin\app.swf" -cp "[DISC]:\Documents and Settings\[USERNAME]\Local Settings\Application Data\Macromedia\Flash 8\en\Configuration\Classes" -cp D:\Projects\[PROJECT]\classes -cp D:\Swf\classes' /> <property name="web.browser.path" value="c:\Program Files\Firefox\Firefox.exe" /> <property name="output.html" value="-url http://localhost/[PROJECT]/index.html?v=0.0." /> <!-- property name="flash.player.path" value="c:\Program Files\Macromedia\Flash 8\Players\Debug\SAFlashPlayer.exe" / --> <!-- property name="flashcommand.path" value="'c:\Program Files\FlashCommand\FlashCommand.exe'" / --> <!-- property name="" value="" / --> <target name="build" depends="build.number.increment, mtasc.compile, run.html" /> <target name="build.number.increment" > <buildnumber file="build.number"/> </target> <target name="mtasc.compile"> <exec executable="${mtasc.path}" > <arg line="${matsc.args}" /> </exec> </target> <target name="run.html"> <exec executable="${web.browser.path}" > <arg line="${output.html}${build.number}" /> </exec> </target> </project>
Как видите, Ant полезен во многих отношениях. И если вас интересует этот действительно мощный инструмент, то вот пара толковых ресурсов для тех, кто только начинает с ним знакомиться, и это по-русски:"Ant за 10 шагов — документация Javatech" и "Автоматизируйте процесс сборки Java программ с помощью Ant". И, конечно, бессмертная статья от Константинера: Разработка Flash-проектов с использованием Apache Ant (доклад на семинаре New Media)!
Я смотрю ты нехило загнался автоматизацией и BPD (Build, Package, Deploy) :)
Ну, до Deploy еще далековато ;)
Есть один побочный эффект у добавления номера версии. Это быстрорастущий кеш, который забивается разными версиями флешек, которые вытесняют другой закешированный контент (если размер кеша ограничен) и вам придется заново качать картинки с других сайтов, на которые вы иногда заходите.
Кроме того, для шареных флешек все равно версию прописать так не получится, а посему я приучил себя уже к более универсальном способу (при локальном тестировании): закрывать окно браузера, в которое загружена флешка и запускать заново после компиляции.
Собственно, ты сам мне про этот способ и рассказывал, если не ошибаюсь ;)
Можешь рассказать, зачем ты тут берешь debug-версию плеера?
...\Debug\SAFlashPlayer.exe
а не релиз?
Мне она больше нравится дла тестирования, например, можно видеть реальную область перерисовки, выбрав соотв. опцию в правокликовом меню.
Вообще, тут никако догмы нет. Это туториал, задача кторого -- подказать читателю возможности инструмента.
Фикс, про размер кэша давно не думаю.. наверное стоило бы ;)
Про шареные флэшки не говри мне.. это больно %)
чото в ИЕ горизонтальный скролинг в 2 страницы при 1280*1024...
Колин, дорогой, спасибо тебе за глюкотчет! Пофиксил.
На сам деле это был очень специальный тест, чтобы узнать, кто из наших пользуется IE ;%)%;);)
Кстати, насчет кэширования:
Я провел тест в Mozilla Firefox 1.5.0.3: много раз обновил страницу, в которой содержался swf-файл с каждый раз меняющимся адресом. Получил интересный рез-т.
Результаты тестирования: Размер некешируемого SWF-файла -- 275 Кб. Кол-во обновлений страницы -- 100 раз. Размер кэша до тестирования -- 0.6 Мб. Реальный размер кэша после тестирования -- 2.8 Мб.
Ожидаемый размер кэша после тестирования -- 28 Мб.
Что наводит меня на интересные размышления: - Возможно, Firefox умеет определять, изменился ли контент в действительности, и, если это не так, не грузит новую версию? - Возможно, он умеет грамотно жать кэш? (но SWF-файлы, как мы знаем, почти не жмутся!)
И еще одно. В Firefox есть встроенный просмотрщик кэша, причем весьма небедный.
Достаточно ввеcти в адресную строку: about:cache
Ха, кажется, я немного ближе к разгадке!
Firefox просто не хранит в кэше предыдущие версии того же самого файла, вот как. Я понял это, исследовав вышеприведенный адрес about:cache (кстати, чтобы он сработал, жмите мо нему средней кнопой или вводите вручную): итак, я покопался в кэше файерфокса через его же встроенный браузер кэша и нашел только одну запись, соответствующую моему SWF файлу. Та запись гласит:
Key: http://localhost/photrproject/bin/app.swf Data size: 275316 bytes Fetch count: 124 Last modified: 2006-05-29 18:51:39 Expires: 2006-05-29 18:52:26
Fetch count ("Количесвоо выборок") -- это реальное кол-во раз, сколько моя флэшара обновлялась. Итак, Firefox хранит только актуальные версии файла. Подсчитыва кол-в его обновлений и храня дату последнего обновления плюс дату истечения кэширования.
Я все больше восторгаюсь этим браузером!
Я пользуюсь IE и меня это устраивает! Страшно? :)
Рост, спасибо за инфу про кеш в FF :)
Только я вот проверил - че-то у меня не выходит так шоколадно, как у тебя.
Загрузил один и тот же файл (абстрагируемся от реального адреса) 6 раз подряд:
http://mysite.com/myfile.swf http://mysite.com/myfile.swf?1 http://mysite.com/myfile.swf?2 http://mysite.com/myfile.swf?3 http://mysite.com/myfile.swf?4 http://mysite.com/myfile.swf?5
Потом посмотрел кеш, как ты сказал (дисковый разумеется) - обнаружил там все эти файлы, у каждого fetch=1. Итого, место в кеше откушано 6 раз. Что-то тут не так..
Рост, перед публикацией своего предыдущего поста, я подумал: "A вдруг дело в том, что я иначе добавляю версию?" И попробовал сделать так как добавляешь версию ты. Так как результат был такой же (множество флешек в кеше), я не стал ничего менять и нажал на кнопку "Отправить". Вероятно, у нас различаются настройки кеша или серверов, отдающих флешки. А может разные FF (1.0.4 у меня)
В URL лучше добавлять не номер бильда а текущее время в микросекундах. Так оно надежнее если несколько раз дергаешь URL в процессе работы приложения.