Flash compiled with Flex SDK very big file size - actionscript-3

I had a simple flash video player I was compiling using Adobe Flash Builder , but now I am compiling it using Flex SDK 4.6 . Flash filesize was 20KB when I was compiling with FB . Now it's 280KB . I know that it adds some swc files to swf build , I have disabled debug etc instructions provided here http://livedocs.adobe.com/flex/3/html/help.html?content=performance_06.html . Is it possible to somehow convert fla components without using mxml ?
Here is my mxml code
<?xml version="1.0" encoding="utf-8"?>
<mx:Application backgroundColor="#000000" xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" layout="absolute" minWidth="320" minHeight="240" creationComplete="initApp()">
<fx:Script>
public function initApp():void{
var p = new video_player(uic);
}
</fx:Script>
<mx:UIComponent id="uic" />
</mx:Application>
video_player.as
....Import statements
public class video_player{
private var uic:UIComponent
var fullScreen:Image;
var rtmpApplication:String;
var streamName:String;
public function video_player(_uic:UIComponent) {
uic=_uic;
if (FlexGlobals.topLevelApplication.parameters.hasOwnProperty("applicationName")) {
rtmpApplication=FlexGlobals.topLevelApplication.parameters.applicationName;
}
if (FlexGlobals.topLevelApplication.parameters.hasOwnProperty("streamName")) {
streamName=FlexGlobals.topLevelApplication.parameters.streamName;
}
vPlayer=new Video(playerwidth,playerheight);
uic.addChild(vPlayer);
init();
}
public function init(){
//add fullscreen image in flash top right , and event handler
//Code to connect to live application and play video using NetConnection and NetStream
}
}
Is there any way around this?

Also I have added option -static-link-runtime-shared-libraries=true so it wont download anything runtime . Without that flash size is 49KB
By setting the above option, you have told the compiler to include all of the Flex framework classes (that are used by your application) in the application SWF. So your SWF grows from 49KB to 280KB.
This is the "RSL" thing (runtime shared library) that #Reboog711 and I were talking about. If you use the Flex RSL's, then all of that Flex framework code is not included in your application SWF. The Flex framework RSL's are signed by Adobe and can be cached by the Flash Player. So using them is always preferable. (Note: I'm assuming this all still works with Apache Flex)
Finally, I wish to reiterate that in Flash Builder there are two basic kind of projects you can create: Flex project, Actionscript project. I'm ignoring the mobile options, but the same applies to them:
An Actionscript project will, in general, result in a smaller SWF because you are not relying on any of the Flex framework classes. It sounds like you could make your video player app even smaller (closer to the 20KB size you originally had) if you were to create an Actionscript project.

Related

How to use an MXML component in my as3 code?

I have made a lot of research on this topic but I could not find any helping answer to my issue. I currently have a 100% as3 application. I would like to add a spark component to my stage eg a datagrid (because it is way more simple and clean to create it with mxml).
FileName : MXMLPractice.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:DataGrid x="0" y="0" width="50" height="50"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="dataField1" headerText="ColumnName1"></s:GridColumn>
<s:GridColumn dataField="dataField2" headerText="ColumnName2"></s:GridColumn>
<s:GridColumn dataField="dataField3" headerText="ColumnName3"></s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
How can I add this component to the stage in my as3 code?
Given my difficulties to find a matching answer, I guess I might be trying to do something not recommended. If that is the case, could you please advise me what to do instead?
My tests so far (compiling but not displaying anything) :
package
{
import flash.display.Sprite;
import mx.events.FlexEvent;
public class Main extends Sprite
{
private var practice:MXMLPractice;
public function Main()
{
practice = new MXMLPractice();
stage.addChild(practice);
}
}
}
In pure AS3 project, you should use AS3 components, that also extend UIComponent as flex components, but designed for pure as3 project. For this task, you will need fl.controls package. You can copy/past ui classes from the installation directory of Flash Professional:
c:\Program Files\Adobe\Adobe Flash CC\Common\Configuration\Component Source\ActionScript 3.0\User Interface\
Next step will be export view representation of ui components to the library in Flash IDE from components window CTRL+F7
It's really hard task.
If you want to use some simple class from Flex SDK like ObjectUtil just copy it to your classes. It will work fine because doesn't have imports.
But visual components are linked with many other classes. For components like grid you have to copy dozens of classes. Each of them also have dependencies and so on.
Probably it's better to modify Flash component or find open source solution.

FlashBuilder 4.6 mx.controls.Button missing?

Im writing my first application in Flash Builder but I have much experience with Flash. I and trying to use the button class in flash builder but my error says "the imports button could not be found". I tried importing flash.display, flash.ui to see it Button was hidden somewhere else. The point is to dynamically load buttons and their labels via xml. Any help is appreciated. Thanks!
<fx:Script>
<![CDATA[
import flash.events.*;
import mx.controls.Button;
private function doAdd(e:Event):void {
var buttonList:XMLList = new XMLList(cutsXML.cut.#name);
for(var i=0; i<buttonList.length(); i++){
var btn:Button = new Button();
btn.label = buttonList[i];
buttonBox.addElement(btn);
}
}
]]>
</fx:Script>
<s:VGroup left="30" right="30" top="50" bottom="30" id="buttonBox">
</s:VGroup>
Im guessing you are creating a mobile app? As mx components are not available (by default) in mobile apps.
You can either use the spark button - spark.components.Button - or manually include the mx components by importing the mx.swc library (found within flex sdk)
Add the mx.swc to your project, that'll do.
In Flash Builder 6.0, do the following:
Right-click on the project in the Package Explorer perspective
Properties...
Flex Build Path (in the left side navigation pane)
Click Add SWC...
Find the mx.swc on your box. On OSX at the time of this writing it was:
/Applications/Adobe Flash Builder 4.6/sdks/4.6.0/frameworks/libs/mx/mx.swc
Click OK
Rebuild your project

Embed images from swf file in flex

How to create vector images swf file in flash, and how can i use the swf file to get images in flex.
Could you please some one help me on this.
Thanks in Advance.
If I understand you correctly, you have a swf file created in Flash CS6 (or similar) that you wish to use in a flex project. Is this correct?
If it is, then you would use swfloader to load your swf file in a flex app.
example:
<fx:Script>
<![CDATA[
import mx.managers.CursorManager;
[Bindable]
public var loadModHome:String = "assets/flashFiles/home_trusted.swf";
protected function analyticsBtn_clickHandler(event:MouseEvent):void
{
loadModHome="assets/flashFiles/home_trusted.swf";
}
protected function integratedBtn_clickHandler(event:MouseEvent):void
{
loadModHome="assets/flashFiles/home_integrated.swf";
}
]]>
</fx:Script>
Then in your component/app/module etc place the swfloader tag and fill it in as needed. Here I have bound the source to a variable called "loadModHome" this makes the swfloader dynamic in that I can assign a new value to my variable and have it unload and load different swf files. I do this by using the click event of two buttons, this allows me to toggle the swf files on the fly
<mx:LinkButton id="analyticsBtn" label="Trusted Analytics" textDecoration="underline"
color="blue" click="analyticsBtn_clickHandler(event)"/>
<mx:LinkButton id="integratedBtn" label="Integrated Billing" textDecoration="underline"
color="blue" click="integratedBtn_clickHandler(event)"/>
<s:SWFLoader id="homeMainSL" x="127" y="10" width="600" height="800"
source="{loadModHome}" click="homeMainSL_clickHandler(event)"
useHandCursor="true" buttonMode="true"/>
To see a working example check out http://www.myfirerules.net. The site is a work in progress. The home page has a s:SWFLoader tag to load the Flash created swf files, the other pages use a s:ModuleLoader tag instead to load swf files created by flex.
Hope this helps
Jim

Handle ExternalInterface Call, comming from local swf file, in Adobe Air 3.4 Actionscript 3 application

So We got a playlist with various swf files, some old as2 animations, some newer.
We download them to a local folder, and can play them fullscreen. all with one AIR (actionscript) application. Now we know that in the newer files there are ExternalInterface.Call(some arguments) calls. And we need to handle them in the hosting AIR application. So far we have a class inherrited from MovieClip, with the following constructor:
public function FlashClip()
{
ExternalInterface.addCallback("FlashPlayerControl1FlashCall",FlashPlayerControl1FlashCall);
}
when we run the application whe got the following error:
Error: Error #2067: The ExternalInterface is not available in this container. ExternalInterface requires Internet Explorer ActiveX, Firefox, Mozilla 1.7.5 and greater, or other browsers that support NPRuntime.
at Error$/throwError()
at flash.external::ExternalInterface$/addCallback()
at Video::FlashClip()[C:\Users\Daan\Adobe Flash Builder 4.6\TINS-v2-1\TINSV2\src\Video\FlashClip.as:12]
at Video::FlashPlayer/BestandOpend()[C:\Users\Daan\Adobe Flash Builder 4.6\TINS-v2-1\TINSV2\src\Video\FlashPlayer.as:43]
On the following line:(FlashPlayer.as:43)
var clip:FlashClip = new FlashClip();
So, My question is this. Is what we are trying to do even possible. Or do we need tot embed a javascript container in the actionscript AIR application? Or does anyone know how we are going to get this to work?? Note: We cannot alter the existing swf files. we dont even have the original .fla's
The documentation says what you are trying to do is not possible:
In Adobe AIR, the ExternalInterface class can be used to communicate
between JavaScript in an HTML page loaded in the HTMLLoader control
and ActionScript in SWF content embedded in that HTML page.
For ExternalInterface to work, it needs to communicate w/a Javascript "layer" that the browsers provide. You won't get this functionality in AIR, unless you load an HTML page that has your SWF content embedded in it.
I've linked to the docs for HTMLLoader which would allow you to do this.
[Edit]
Appending a simple AIR app (note it's Flex 3.6, sorry that's what my client uses) that loads a web page, in case it helps.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
width="800" height="600"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
private function onCreationComplete():void
{
var loader:HTMLLoader = new HTMLLoader();
var request:URLRequest = new URLRequest("http://www.adobe.com");
loader.width = 800;
loader.height = 600;
loader.load(request);
var uic:UIComponent = new UIComponent();
uic.addChild(loader);
addChild(uic);
}
]]>
</mx:Script>
</mx:WindowedApplication>

How many levels deep can you nest swf's - will 3 work - like child inside parent inside grandparent?

The code at the bottom of this post nests an AS2 "player" inside a Flex app (AS3). Look at the part that says "[AS2 player swf]". That AS2 player swf has almost no code - just one function that loads an asset from a remote server. Very simple:
this.onLoad = function(){
content.loadMovie("http://URL_TO_REMOTE_SWF");
};
And it has no other assets. Just one MovieClip - "content".
So we've got a Flex app that loads an AS2 swf that loads a remote swf. No dice. Remote swf doesn't load and display. No errors reported.
Important: The AS2 app on its own works. If I go navigate to it in my file system and double click, remote swf does indeed load and display. So I've established that the unwrapped AS2 swf player works and does indeed load remote swf's. Something about nesting that player inside the Flex app creates a problem. Are you not allowed to do this - 3 levels of swf nesting (child - parent - grandparent)?
UPDATE: Target remote swf's load and display fine directly in Flex as well (skipping AS2 swf). So problem doesn't appear to be with AVM1/AVM2 discrepancy between target content and Flex app. Could be AVM1/AVM2 problem with how the Flex app displays the AS2 swf but only when it contains content.loadMovie("http://URL_TO_REMOTE_SWF"). Loads and displays without that line.
UPDATE: This is a Flex packaged IOS application and thus is subject to ActionScript restrictions for dynamically loaded code. But it doesn't work in a regular Flex (non packaged IOS) app either which is not subject to these limitations. THE FOLLOWING CODE SHOULD WORK AS FAR AS I CAN TELL IN A REGULAR FLEX BROWSER BASED APPLICATION.
<?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"
initialize="init()">
<fx:Script>
<![CDATA[
import mx.core.UIComponent;
private var request:URLRequest = new URLRequest("[AS2 player swf]");
private var loader:Loader = new Loader();
private var myComponent:UIComponent = new UIComponent;
private function init():void{
myComponent.percentHeight = 100;
myComponent.percentWidth = 100;
loader.load(request);
myComponent.addChild(loader);
player.addElement(myComponent);
}
]]>
</fx:Script>
<s:Group id="player"
height="100%" width="100%"/>
</s:Application>
Since all Sprites and MovieClips are both display objects and display object containers, you could theoretically keep nesting them forever. There are physical restraints, of course, but I see no reason why there should be a limit other than memory and processing power (at some point, refreshing the screen will become sluggish, and eventually painful to wait for).
I've searched the web to see if I could find any information about a built-in limit enforced by the AVM, any documents or error codes that would suggest there is one, but I couldn't find anything at all. Of course, that doesn't mean there isn't - it just means the limit hasn't been reached by many people yet ;)
So if anyone else knows more...
EDIT
Since the information about your loaded MovieClip is new, here's my update: AVM1 (AS1 & 2) SWFs don't always execute in the same way when loaded into an AVM2 (AS3) movie. This has nothing to do with the number of nested display objects. I originally thought this was because the _lockroot property was removed in AS3, but I've searched a bit and found out it is assumed true by default, and should therefore not be a problem.
There may be many things about your scenario that are different from when the file runs on its own, and I would start by looking at these:
Do you use relative path names to load other data into the AS2 swf?
Do you get any error messages (particularly, security sandbox violation errors)?
Does your AS2 SWF rely on external variables to be set (FlashVars)
Does your AS2 SWF need ExternalInterface access?
FINAL EDIT
Since this new info has just come up:
There is absolutely no way to execute dynamically loaded AVM byte code on an iPad at runtime, for the same reason that there is no Java VM and no Flash Player for iOS: Apple does not allow the execution of dynamically loaded byte code at all. Period.
Hence, you can load and play SWF animations, but not ActionScript. It will simply be ignored. Also, neither of the apps that you did run is in fact AVM byte code - they are compiled into LLVM byte code instead.
You will have to find a way to check for the end of the animation that does not involve stop() commands. Perhaps this can be done by checking frame numbers from your AS3 container?
To answer you question directly, yes, you can load AS2 swfs that way. And you code looks correct to me.
I suspect it is loading the AS2 swf fine, but that the AS2 swf is not initializing correctly for some reason. Perhaps it is a video player that has no visible assets besides the loaded video. AS2 tends to fail without throwing errors, which makes it hard to debug. I would suggest publishing an AS2 swf with some graphics in it but with no code that could fail. No code at all. Maybe just a timeline animation of a moving circle or something, then load that. In that way you can eliminate your Flex code as the source of the problem.
If it turns out that your test movie works, then you will need to determine what resource the loaded swf is expecting that it is not receiving.