Работа с RSL подразумевает две довольно разные задачи. Одна задача -- собрать проект так, чтобы flex framework подключался как RSL, а не входил в состав swf-файла. Другая задача -- создание собственных RSL библиотек и их подключение. Первая задача проще, ибо библиотеки уже есть. С нее и начнем, а другую задачу рассмотрим позже :)
Итак, RSL суть Runtime Shared Library. Из названия ясно, что это библиотека (library), которая загружается и линкуется во время исполнения (runtime) вместо того, чтобы статически линковаться при компиляции. И она предназначена для совместного использования одновременно несколькими разными приложениями (shared). Впрочем, последнее опционально, можно обойтись и одним приложением :)
RSL бывают трех видов: Standard RSLs, Cross-domain RSLs, Framework RSLs. Но я бы сказал, что двух видов.
Framework RSLs сделаны и подписаны адобом, в них входят классы, составляющие flex framework. И они существуют в виде файлов с расширением swz. Что значит "подписаны"? Это значит, что данные swz файлы подписаны адобовским сертификатом, и поэтому флеш-плеер умеет отличить их от подделки. К примеру, если вы сами скомпилируете флекс фреймворк (со своими модификациями или без), то вы не сможете подсунить это флэш плееру как swz файл (но можете подсунуть как Standard RSL). Взять эти swz негде, кроме как у адоба.
В отличие от них пользовательские RSLs (Standard и Cross-domain) создаются самим разработчиком и существуют в виде swf файлов. Они должны быть на том же домене, что и приложения, их использующие (про кросс-доменные RSL пока говорить не будем).
Фишка Framework RSL в том, что они кешируются независимо от конкретного приложения. Если пользователь где-то загружал какое-то флэш приложение (не обязательно ваше) и с ним загружал такие же swz, какие использует ваше приложение, то эти swz есть у пользователя в кеше. И теперь, когда пользователь добрался до вашего приложения, эти swz не будут грузиться еще раз. И это очень хорошо, поэтому что это позволяет сильно уменьшить размер swf файла и сильно ускорить его загрузку. Чем, собственно, мы сейчас и займемся.
Еще такой нюанс, что Standard RSL будет хранится в кеше браузера, а Framework RSL -- в кэше флэш плеера (под линуксом это тут: ~/.adobe/Flash_Player/AssetCache).
На этом с теорией все, ибо это все очень подробно описано в адобовской документации. А перейдем сразу к практике.
Сперва нужно решить, какую версию Flex SDK мы будем использовать. Flexmojos нам позволяет выбирать из целой кучи сборок Flex SDK ( вот гляньте сюда, сколько их тут :) Ну и какую версию нужно использовать? Самую-самую последнюю? Однако нет.
Давайте-ка посмотрим вот сюда: Flex 4 Downloads. На момент написания статьи тут лежит Latest Milestone Release Builds версии 4.1.0.16076 и несколько версий Nightly Builds. Нужно скачать любой Flex SDK отсюда. Зачем? Ведь у нас есть Flexmojos и он сам все скачает в свой репозиторий. Однако это нужно, ибо в составе Flex SDK есть swz файлы, а в репозиториях Flexmojos нет. А они нам нужны.
Я использую версию 4.0.0.14159. Более поздние версии требуют флэш плеер 10.1, а у меня он тормозит, виснет, и временами не показывает исключения (особенно сильно тормозит и виснет при работе с веб-камерой). Так что я использую флэш плеер 10.0. Из-за этого и фреймворк использую не самый свежий :)
Итак, у нас есть Flex SDK. Давайте заглянем сюда: flex_sdk_your_version/frameworks/rsls. Вот они родимые :)
datavisualization_4.1.0.16076.swf 480 Kb datavisualization_4.1.0.16076.swz 285 Kb framework_4.1.0.16076.swf 1022 Kb framework_4.1.0.16076.swz 613 Kb osmf_flex.4.0.0.13495.swf 148 Kb osmf_flex.4.0.0.13495.swz 96 Kb rpc_4.1.0.16076.swf 203 Kb rpc_4.1.0.16076.swz 129 Kb spark_4.1.0.16076.swf 492 Kb spark_4.1.0.16076.swz 312 Kb sparkskins_4.1.0.16076.swf 69 Kb sparkskins_4.1.0.16076.swz 54 Kb textLayout_1.1.0.604.swf 257 Kb textLayout_1.1.0.604.swz 154 Kb
Тут и сам флекс фреймворк, и спарк компоненты со скинами, и Remote Procedure Call, и Text Layout Framework, и Open Source Media Framework, и Data Visualization. Каждая библиотека есть в виде swz (подписаная) и в виде swf.
Теперь создадим небольшой проект. Он будет простенький, типа Hello World. Но мы чутка заюзаем Text Layout Framework и тем самым заметно увеличим swf файл. И потом его уменьшение будет еще нагляднее :)
(Кстати, вот клевый тул, чтобы поиграться с TFL разметкой Text Layout Editor)
Вот будет наше приложение:
<?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:flow="http://ns.adobe.com/textLayout/2008"
width="400" height="250">
<s:VGroup>
<s:Label text="Hello"/>
<s:Label text="World"/>
<s:TextArea width="100%" height="100%" text="Hello">
<s:textFlow>
<s:TextFlow>
<s:p>
<s:span fontSize="29" color="0xff0000">Hello</s:span>
<s:span fontSize="29"></s:span>
<s:span fontSize="29" color="0x66ff00">World!</s:span>
</s:p>
</s:TextFlow>
</s:textFlow>
</s:TextArea>
</s:VGroup>
</s:Application>
И вот пом проекта:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>try-flexmojos</groupId>
<artifactId>flexmojos-swz</artifactId>
<version>1.0</version>
<packaging>swf</packaging>
<properties>
<flexmojos.version>3.7.1</flexmojos.version>
<fdk.version>4.0.0.14159</fdk.version>
<fp.version>10.0.42</fp.version>
<www.root>/var/www/html</www.root>
</properties>
<build>
<sourceDirectory>src/main/flex</sourceDirectory>
<testSourceDirectory>src/test/flex</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<configuration>
<output>${www.root}/flexmojos-swz/demo.swf</output>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${www.root}/flexmojos-swz/rsl</outputDirectory>
<resources>
<resource>
<directory>src/main/resources/rsl</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>${flexmojos.version}</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>com.adobe.flex</groupId>
<artifactId>compiler</artifactId>
<version>${fdk.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>asdoc</artifactId>
<version>${fdk.version}</version>
<type>zip</type>
<classifier>template</classifier>
</dependency>
</dependencies>
<configuration>
<debug>true</debug>
<targetPlayer>${fp.version}</targetPlayer>
<warnings>
<noConstructor>false</noConstructor>
</warnings>
<rslUrls>
<rsl>http://fpdownload.adobe.com/pub/swz/flex/{version}/{artifactId}_{version}.swz</rsl>
<rsl>rsl/{artifactId}_{version}.swz</rsl>
</rslUrls>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>playerglobal</artifactId>
<version>${fdk.version}</version>
<classifier>10</classifier>
<type>swc</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>flex-framework</artifactId>
<version>${fdk.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>framework</artifactId>
<version>${fdk.version}</version>
<type>swc</type>
<scope>caching</scope>
</dependency>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>spark</artifactId>
<version>${fdk.version}</version>
<type>swc</type>
<scope>caching</scope>
</dependency>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>sparkskins</artifactId>
<version>${fdk.version}</version>
<type>swc</type>
<scope>theme</scope>
</dependency>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>textLayout</artifactId>
<version>${fdk.version}</version>
<type>swc</type>
<scope>caching</scope>
</dependency>
<dependency>
<groupId>com.adobe.flexunit</groupId>
<artifactId>flexunit</artifactId>
<version>4.0-rc-1.1</version>
<type>swc</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.adobe.flexunit</groupId>
<artifactId>uiRunner</artifactId>
<version>4.0-rc-1.1</version>
<type>swc</type>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>sonatype-repository</id>
<url>http://repository.sonatype.org/content/groups/flexgroup</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>sonatype-repository</id>
<url>http://repository.sonatype.org/content/groups/flexgroup</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Комментарии по пом файлу:
Сперва соберем приложение без указания scope=caching для артефактов, и поглядим его размер -- 1019 Kb. Неплохо для Hello World :)
Теперь включим scope=caching и посмотрим, что получилось -- 75 Kb. Ага, ну что скажете? Неплохо так похудел swf.
Все хорошо, но, как обычно, есть кое-какие нюансы :)
textLayout.swz помечена другой версией. Поскольку мы не можем задавать rslUrl индивидуально для каждой swz, а задаем общую для всех маску, то нам придется сделать небольшой трюк -- переименовать textLayout_1.0.0.595.swz в textLayout_4.0.0.14159.swz. Конечно, по первому url с сайта адоба она не загрузится, и тут сработает второй урл. Или можно не указывать caching для этого артефакта и получить лишние 250Kb в наш swf (что в общем-то не критично). Еще один вариант -- подключить textLayout.swf как Standard RSL. Но я остановился на первом варианте.
После того, как мы указали caching для артефактов, мы уже не сможем запустить нашу флешку локально. Во-первых, потому что у нас пока нет swz-файлов в папке rsl рядом с нашим flexmojos-swz-1.0.swf (в target). Во-вторых, даже если бы и были, то не загрузилась бы, потому что swf не может загружать локальные ресурсы. Тут нужен веб-сервер и запуск через http://localhost/
Поэтому переходим к следующему этапу.
Итак, нам нужно развернуть файлы на локальном веб-сервере так, чтобы рядом с swf-файлом была папка rsl и в ней все необходимые swz-файлы. Для начала положим нужные нам swz в папку src/main/resources/rsl. А понадобится нам следующие:
framework_4.0.0.14159.swz spark_4.0.0.14159.swz sparkskins_4.0.0.14159.swz textLayout_1.0.0.595.swz (который мы переименуем в textLayout_4.0.0.14159.swz)
Затем воспользуемся maven-resources-plugin и попросим его скопировать эти файлы в ${www.root}/flexmojos-swz/rsl. Обязательно нужно отключить filtering, иначе плагин попортит нам swz и они перестанут загружаться.
Затем добавим в configuration параметр output, который скажет компилятору куда класть swf файл.
В обоих местах мы используем переменную ${www.root}, которая указывает на рут локального веб-сервера. В данном случае эта переменная определена прямо в пом, но на самом деле такие параметры лучше выносить в .m2/settings.xml, потому что они будут отличаться на разных машинах у разных разработчиков.
Ну и все, теперь mvn install и можно открывать в браузере http://localhost/flexmojos-swz/demo.swf и любоваться :)
Проект можно скачать тут.
Comments
Anonymous (not verified)
Sun, 01/09/2011 - 18:26
Permalink
Ты показал не все депенденси
Ты показал не все депенденси в поме. А так былобы хорошо заходить на твою страничку и копипастить. Удалять не добавлять.
yzh44yzh
Sun, 01/09/2011 - 18:26
Permalink
Не, зависимости указаны все.
Не, зависимости указаны все.
Я именно такую цель и ставил -- чтобы можно было скопипастить пом и он сразу заработал у всех. Для этого и проекты целиком выкладываю, ибо не в одном только поме дело.
В данном случае проблема можеть быть в переменной ${www.root}. Там указан путь /var/www/html, а такой путь не на каждой машине есть :)
Если у тебя проект не собирается, пришли, плз, мне на мыло, что мавен выводит в консоль.
Anonymous (not verified)
Sun, 01/09/2011 - 18:27
Permalink
По умолчанию rslUrls равно /
По умолчанию rslUrls равно /{contextRoot}/rsl/{artifactId}-{version}.{extension}
То есть если вы не используете и не хотите использовать fpdownload.adobe.com, то и указывать ничего не надо.
Для веб-сервера — WAR — вручную ничего копировать не нужно, достаточно заклинания copy-flex-resources. Таким образом, зачастую (и в моем проекте так и есть), достаточно лишь указать scope для артефакта и все. Но это мелочи — по существу добавить нечего, спасибо :)
yzh44yzh
Sun, 01/09/2011 - 18:28
Permalink
Еще один нюанс: в
Еще один нюанс: в оригинальных swz файлах имя артефакта и версия разделяются подчеркиванием, а в умолчальном rslUrls дефисом. Этот нюанс можно не заметить и не понимать, почему swz не грузятся.
Так что нужно либо указать явно rslUrls, либо не забыть поправить имена всех swz файлов :)
Anonymous (not verified)
Sun, 01/09/2011 - 18:28
Permalink
Заработало, только после того
Заработало, только после того как добавил:
http://fpdownload.adobe.com/pub/swz/crossdomain.xml
как описано в https://docs.sonatype.org/pages/viewpage.action?pageId=7045277
Add new comment