注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

神魔破杜梓的叨叨堂

Programming every day!

 
 
 

日志

 
 
 
 

使用Flash CS3 和Adobe AIR 由浏览器过渡到桌面  

2008-08-06 17:52:14|  分类: My Tech |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
原文来自InsideRIA
A step by step guide for designing desktop applications for developers and non-developers

A Little Piece of History

Every trend in history moves in waves, whether it is clothes from the 60's, music from the 70's or ideas from the 80's. 84 to be exact. This was the year that Apple started their 'Desk Ornaments', little programs that live in their own virtual space, called a window. Unknown then, this event would give birth to, what we now know as, desktop applications. A lot happened in the years in between; from MIT's Athena Project to Yahoo's Webstart and Microsoft's Active Desktop to Apples Dashboard. Fast forward to 2005 where Adobe introduces us to the Apollo Project which later becomes Adobe AIR. A cross platform ActionScript API specifically for desktop development utilizing existing web technologies. Allowing developers to create and deploy applications ranging from small and fun to massive enterprise level tools.

Assuming you are a Flash Developer and create websites and/or RIAs for a living (or for fun), how would you make the switch from browser to desktop development? With this guide I will lead you through this process step by step. As a sample project we will create a drag and drop mp3 player. The reason why is it encompasses most of the AIR APIs and no matter what the size, these steps can be applied to any project. Everything is done within the Flash IDE.

Expectations.

We all use desktop applications; our calculator, music player, text editor etc. When using these apps, our expectations are different when using a website. On a website the logo links back to the homepage, a single click opens a page and the menu includes a button that says 'home', to name a few. Applications have a different pattern. They have menu- and toolbars, right click shows a context menu and a settings option that allows you to adjust things to fit your needs. What they have in common is that they both have a well thought through design that is tested against usability. A well written, well designed application or website does not impose questions on users but removes them.

Users expect applications to behave differently than websites and there are some design issues to be aware of. For instance; if you have an media player like Winamp, users expect that when you double click (or single click, depending on your OS settings) an mp3 file, it gets loaded, visually shows a que of files and starts playing with the first song. However when you drag and drop files in the player, it should behave the same as the previous operation.

When in the browser you can load in an XML file that holds your mp3 files and load those in the Flash Player and start playing them, visually showing them in a list. Thus you are confined to the files that reside on the server and simply can't do any of the operations when using a desktop app. When developing for AIR you can. Since you are not confined to a browser, a whole lot more becomes available such as, setting file type associations, drag and drop, loading one or multiple files and clipboard access.

Lets break this down and create a very basic drag and drop music player with file association's to mp3 files:

The way to set file type associations is through the descriptor file. (found in the same directory as our flash, projectname_app.xml)
Our entry point will be the node.

 
<fileTypes>
<fileType>
<name>mp3Player.MP3</name>
<extension>mp3</extension>
<description>Mp3 File</description>
<contentType>audio/mpeg</contentType>
<icon/>
</fileType>
</fileTypes>

Before we start writing any code, make sure you have the latest update for Flash CS3, this allows you to create AIR applications. You can download Adobe AIR Update for Flash CS3 Professional.

You can grab this update strait from the Flash IDE by selecting the Flash Help menu > Updates. This opens the Adobe Update Manager. Or you can find it online http://www.adobe.com/support/flash/downloads.html.

Lets start writing code. First we define our imports, setup the listeners and set some variables for our sound object. The AirLogger Class you can download here http://www.funky-monkey.nl/blog/2008/05/13/air-logger-v100/

 
import flash.desktop.*;
import flash.events.NativeDragEvent;
import AirLogger;

We create an empty array to hold a reference to the songs on the filesystem and an int(datatype) for remembering what song we are playing. Later on we can reference the current song with this index pointer.
 
var fileList:Array = new Array();
var currentPos:int = 0;
//
var snd:Sound = new Sound();
var sndChannel:SoundChannel = new SoundChannel();
var sndRequest:URLRequest;

var fileClicksLdr:Loader = new Loader();

startApp();

function startApp(evt:Event = null):void
{

Since we want to associate .mp3 files with our application, we are setting this so when users click an associated file, our player opens. (Just remember that users have their own preferences set up for handling specific file types, normally you would present them with a settings dialog where they can check this option).

NativeApplication.nativeApplication.setAsDefaultApplication("mp3"); When a users drags files in our player, we want to cue them and start playing the first file. For this to happen we must create event handlers (listeners) to respond.

stage.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, onDragEnter);
A movieclip called 'hit' that is on top of the logo, has multiple functions. A drop box for our file(s), dragging the whole applications and when double clicked it closes.
 
hit.doubleClickEnabled = true;
hit.buttonMode = true;
hit.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onDragDrop);
hit.addEventListener(MouseEvent.MOUSE_DOWN, onDragApp);
hit.addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick);

When users click a file that is handled by our application, we want to invoke an event and handle that click coming from the users operating system. The first argument we receive is the file the user clicked.

NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, handleFileClicks);
dont forget to close the function with a curly brace.
 

function handleFileClicks(evt:InvokeEvent):void
{
var args:Array = evt.arguments as Array;
if (args.length)
{
var fileToOpen:String = String(args[0]);
fileClicksLdr.load(new URLRequest(fileToOpen));
addChild(fileClicksLdr);
loadSound(fileToOpen);
}
}

We create our handler functions, and check if the dragged in file is a valid file type. In a real world application you would present the user with a dialog box, show a picture or move away your window if this is not of the correct type. Please note that this event keeps getting fired as long as we mouseover (without releasing the file).

function onDragEnter(evt:NativeDragEvent):void
{
fileList = evt.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
currentPos = 0;
for(var i:uint; i < fileList.length; i++)
{
if(fileList[i].extension == "mp3")
{
AirLogger.log("file name :" +fileList[i].name);
NativeDragManager.acceptDragDrop(hit);
}
}
}

When we release our files into the player, the onDropDrag gets fired, now we call a method to play the dropped files.

function onDragDrop(evt:NativeDragEvent):void
{
nextBtn.addEventListener(MouseEvent.CLICK, loadNext);
prevBtn.addEventListener(MouseEvent.CLICK, loadPrev);
nextBtn.buttonMode = true;
prevBtn.buttonMode = true;

loadSound(fileList[0].url.toString());
}

We also need to listen to interaction with the window, we need to be able to close it and move it around.

function onDragApp(evt:MouseEvent):void 
{
stage.nativeWindow.startMove();
}
function onDoubleClick(evt:Event):void
{
stage.nativeWindow.close();
}

In the loadSound we're setting up a new request and load the file. If things go wrong, we can output that by adding an event listener to respond to errors. We also want to show so called ID3 tags, MP3 metadata, so we have a textual representation of what we are hearing. Why am I setting the trackInfo_txt textfield to “Track has no ID3 data” in the loadSound method? I cant set it in the onID3Handler, because if there is no ID3 data in the file, the event doesn't get fired.

 
function loadSound(file:String):void
{
if(snd && sndChannel)
{
snd = null;
snd = new Sound();
sndChannel.stop();
}

sndChannel = new SoundChannel();
var sndRequest:URLRequest;

sndRequest = new URLRequest(file);
snd.load(sndRequest);
sndChannel = snd.play();

snd.addEventListener(Event.COMPLETE, onSoundLoadingComplete);
snd.addEventListener(IOErrorEvent.IO_ERROR, onSoundLoadingError);
trackInfo_txt.text = "Track has no ID3 data";
snd.addEventListener(Event.ID3, onID3Handler);
AirLogger.log("sound playing");
}
function onID3Handler(evt:Event):void
{
if(evt.target.id3.artist != "" || !evt.target.id3.songName != "") {
trackInfo_txt.text = evt.target.id3.artist + "\n" + evt.target.id3.songName;
}
AirLogger.log("artist : " + evt.target.id3.artist );
AirLogger.log("sound length : " + evt.target.id3.songName );
}

We need to check if the current song is still within the bounds of the fileList Array when pressing the next of previous button.

 
function loadNext():void
{
if(currentPos == fileList.length -1)
{
currentPos = 0;
} else {
currentPos ++;
}
loadSound(fileList[currentPos].url.toString());
}

function loadPrev(evt:MouseEvent):void
{
if(currentPos != 0)
{
currentPos--;
} else {
currentPos = 0;
}
loadSound(fileList[currentPos].url.toString());
}

function onSoundLoadingComplete(evt:Event):void
{
snd.removeEventListener(Event.COMPLETE, onSoundLoadingComplete);
// trace out a message for user.
sndChannel = snd.play();
}

function onSoundLoadingError(evt:IOErrorEvent):void
{
snd.removeEventListener(IOErrorEvent.IO_ERROR, onSoundLoadingError);
// trace out a message for user.
}

Now that we have our code setup, we'll leave it for now.

User Experience

We live in a visual world, feel with our hands and we perceive through our eyes. I know this is stating the obvious, however when we apply this knowledge to our application it becomes clear.

I'm making a bold statement here when I say that the look and feel is the most important part of our application. It is an extension of our online identity. This is the first thing our users see, and judge it by its looks and its behavior. Actually the feel and responsiveness, is the most important, the way you and your users interact with it. This is what sets you apart from your competitors.

Take a look at the AOL top 100 video application.

screen1_aoltop100.jpg

When it opens it shows you a splash/loading screen then loads up the main content. The interface is very clean, the loading is rapid and the showing of screens smooth. You can choose from different views, panels slide in and out. It's a very complete experience, and very responsive.

If you compare this to their website you see the following; pages contain a lot more information, that is not that relevant to users that only wish to see videos. So the tool they created allows them to do just that and a little bit more.

Back to our sample application. When it behaves and responds accordingly, your users will keep their focus and won't treat it like 'just another app'. Thus clicking the big X in the top corner.

A Different Jacket.

In this section I'll be talking about the differences between a generic jacket vs a custom tailored jacket. On most days wearing a generic jacket will do just fine. The fit is ok, the length is fine, and you got used to wearing it. However there are days where a generic jacket just won't do, you want to wear your special custom tailored jacket, with fine lining, sleeves that are just right and cuflins to match. It all depends on the occasion.

When it comes to designing applications there isn't much difference. Depending on the needs of the project you'll go for the default system chrome, but sometimes you'll want to have a custom chrome (skin) for your application. The difference with websites is that you are bound to the browser, and do not have control over its shape or skin. When creating AIR apps you can, but that doesn't mean you have to. When Flash 8 was came out we were able to create drop shadows, blurs, glows and bevels straight from Flash. Everybody was applying these to their projects. Sometimes it added that extra sauce to a project and enriched the experience, sometimes it did the opposite. Just because you can does not mean you have to.

Most AIR applications available use a custom chrome because it enhances the brand experience. For example, the eBay desktop lets the user choose between custom or system chome.

eBay_desktop_default_chrome.jpg


eBay_desktop_custom_chrome.jpg

One of the applications that does not do so is the The Finetune player. Since the design of their site and desktop player are in the same style, it creates a uniform experience. If they where to use the custom chrome, it does not provide anything extra to the experience.

使用Flash CS3 和Adobe AIR 由浏览器过渡到桌面 - hydra1983 - Edisons Closet
Finetune( http://www.finetune.com/) and their desktop tool ( http://www.finetune.com/desktop )

What I've noticed while developing using either custom or default chrome, is the memory usage of your application. When you don't correctly clean up after yourself, your application becomes slow and unresponsive. I recommend writing a method that checks if a specific object has listeners on it and remove them when they are not in use any more.

Best practices for setting up listeners are making sure that they are used as a weak reference.

We do this by setting the fith parameter in the addEventListener function. The syntax for setting up a listener is the following:

someObject.addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void In the Flash help it states the following about the useWeakReference parameter; “The useWeakReference parameter allows you to specify whether the reference to the listener function is weak or normal. Setting this parameter to true allows you to avoid situations in which listener functions persist in memory even though they are no longer needed. Flash Player uses a technique called garbage collection to clear objects from memory that are no longer in use. An object is considered no longer in use if no references to it exist. The garbage collector disregards weak references, which means that a listener function that has only a weak reference pointing to it is eligible for garbage collection.”

This means that if we set it to false and there are no longer any references to any objects that use this listener, it gets cleaned up by the garbage collector.

So now its time to go through our already written code and change the listeners so they use weak references. Like so:

 
hit.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onDragDrop, false, 0, true);
hit.addEventListener(MouseEvent.MOUSE_DOWN, onDragApp, false, 0, true);
hit.addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick, false, 0, true);

Try to familiarise yourself with this so it becomes part of your daily routine when adding and/or removing listeners. I think you can manage the rest of the code yourself.

Names and Icons

As I mentioned earlier, user experience is about the looks of the application but also that of the icon. Choosing or creating an icon is tightly coupled with the name of your product / application. There is a great article by Guy Kawasaki called 'The Name Game' (http://blog.guykawasaki.com/2006/02/the_name_game.html) about choosing names for your brand/product/company. Since the name of your app is something users will remember, I truly recommend this article. Users will share experiences based on you brand- or product name, try to google it, and use it as a verb. Coming up with a good name doesn't have to be that hard, but it is a crucial step.

If name and icon are tightly coupled, the icon should reflect part of what the program does or reflect the name, or both. I find it easier to come up with an icon for a small application then for a big bulky one, the reason is quite simple. Finding a visual metaphor for a application that does just one thing is is a lot less complex than finding one for a program that has loads of functionality.

It doesn't matter if you are designing a logo for a website or for an AIR application, the process is the same.

A good quality icon communicates the appropriate message and if designed properly it will leave a good impression on your users. On most occasions a corporate logo will be used or an icon that represents the product or the function that the program performs. As a side note; Since I recently made the switch to a Mac I truly think that Apple has done a nice job designing their icons. Take a look at their Mail, Time Capsule or iChat icons. They are well designed and get the targeted message across; they are recognizable icons.

On most operating systems you have something similar to an icons bar; on Windows you have the 'Quick Launch' bar and on OS X you have the 'Dock'. In both places the icon stays here permanent, as opposed to only showing up when the program runs. This is a good way to familiarize users with your brand. Look at the icons of any Adobe product; the theme they chose for its current release, the periodic table, is represented in every program they create, therefore users are familiar with it because it is consistent.

If and when you are creating an application it is well worth investing in a good icon/graphic designer to take your brand experience one step further and create an icon that sticks. A well designed icons speaks for its self.

However when an icon is poorly designed and does not communicate the appropriate message it causes confusion. Even a icon that is designed well, can get the wrong message across. And even though your icons may look great at 128x128 pixels, take special care when creating smaller size icons like 32x32, 24x24 and 16x16 pixels. Because these icons are smaller, it means you have less space to get your message across, even more so when used with a text label.

An image says more than a thousand words and that is exactly the problem. We tend to interpret things based on experience, culture and personal preference. Icons, no matter what size, will say more than a thousand words, and a word can say more than a thousand images, when combined in the right way they convey the appropriate message.

Take a look at the following screen shot for what I'm talking about (icons mac and windows link: http://www.apple.com/macosx/features/mail.html).

使用Flash CS3 和Adobe AIR 由浏览器过渡到桌面 - hydra1983 - Edisons Closet

使用Flash CS3 和Adobe AIR 由浏览器过渡到桌面 - hydra1983 - Edisons Closet

Components.

I can be very short about this. When your application is designed in a specific style, you don't want to use the standard skin that the components have that come with Flash. It's not that they are no good, it's that you want be consistent with the design and make sure that everything looks as a whole. Component skinning in Flash CS3 has become a breeze. Just drag an instance on the stage from your Components Panel, double click it and change the visual appearance. There is nothing to it. Even though they simplified the process skinning, this can be a time consuming task if done for the first time. Personally I prefer to create my buttons and components myself as MovieClips, set the linkage identifier, load the swf in my application and dynamically load that that asset depending on the linkage as a class. So I can call var assetButton:MovieClipButton = new MovieClipButton. More on this later.

The benefit of using Splash Screens.

To be very short, loading assets. Splash screens are ideal for preloading assets and content.

Wikipedia says “Splash screens are typically used by especially large applications to notify the user that the program is in the process of loading. In other words, they provide feedback that a sometimes lengthy process is under way. A splash screen disappears when the applications main window appears. Splash screens typically serve to enhance the look and feel of an application or web site, and hence are often visually appealing, and may also have animations, graphics and sound.” When you preload a website's sounds, XML, images etc, you present your user with a loading text or image, sometimes even a game.

使用Flash CS3 和Adobe AIR 由浏览器过渡到桌面 - hydra1983 - Edisons Closet


splashScreen_flashcs3.jpg

With AIR development it gives you the opportunity to show the name of your application with a nice logo while loading, thus giving the feel of any other program. It is always wise to implement a way to let users disable the splash screen.

Other benefits of using a splash screen are:
Letting users set the initial language, then load the appropriate data defining button names and other application labels. This can be an XML file from an remote location or one that you packaged this your application.

Highlight specific features, news or other points of interest.

One big downside is that it also increases the start time of your application. When loading time is to long users tend to get bored and it can lead to them not using you program.

I personally use the splash screen to also load in my applications skin. Choosing to load them locally or from a remote location depends on the project you are doing and whether or not your application can go on line to retrieve its data. This also applies if you use XML to store your data.

As I mentioned earlier I dynamically load my assets as Classes. Here's what I'd do: I create an new flash document and herein I create my assets, animations etc. Then I set the linkage identifier to that MovieClip that holds my skin element or animation. First you create member variables to hold a reference to the MovieClip in our library, datatype it to Class, load the clip and call getDefinition() with the linkage identifier. For demonstration purposes, lets create a movieclip with a custom button in it and set the linkage to MyOwnButton (see screenshot linkage_id.jpg ). Check the 'Export For Actionscript' option. This clip is now available to us as runtime. Make sure you publish this file as AS3, Flash player 9.

 
import flash.display.Loader;
//
var MyButtonClass:Class;
//
function loadAssets():void
{
var assetLoader:Loader = new Loader();
assetLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, assetLoaderComplete false, 0, true);
assetLoader.load(new URLRequest("assetLib.swf"));
}

When the assetLibrary.swf is done loading it calls the assetLoaderComplete handler that handles the request and utilizes the getDefinition() method to get the class definition by a string.

function assetLoaderComplete(evt:Event):void
{
// remove your listener
evt.target.removeEventListener(Event.COMPLETE, assetLoaderComplete);
var appDomain:ApplicationDomain = evt.target.applicationDomain;
// save the the movieclip as class
MyButtonClass = appDomain.getDefinition("MyButton") as Class;
}

Now can create and instance of the MyOwnButton, simply by calling:

 var myButton:MovieClip = new MyButtonClass();
addChild(myButton);
This technique is not bound to AIR development and can also be used for websites, as long as you use AS3. If you want to use this for AIR, you must package your assetLib.swf along with the application.

installer_settings.jpg

Tying it all together.

When deploying your website to the web, you embed your swf file within a HTML file (or any other flavour file) and put it on a server. In your HTML you define a table or a div, some meta tags and other bits and bobs. When deploying an AIR project it is a bit different. After choosing to publish it to AIR 1.0, from your public settings, you select Commands from the menu. Here you select the option 'AIR - Application and Installer Settings'. This is basically a GUI for the descriptor file we talked about earlier.

Fill in all the details about your application, set an icon and maybe some other files you want to include in your build, version number and a description. You can also set the fileType association under the advanced button so don't have to edit the file itself.

When you are all done, click on the 'Publish AIR file' button. The file resides in your project folder.

You first application is a fact! Now its time to test it!

Conclusion.

We talked about what to expect from an desktop application made in Flash, the do's and dont's, what to look out for when creating icons, when to choose default chrome or go for your own, and created a mp3 Player as a sample project. All source files can be downloaded here so you can start
  评论这张
 
阅读(481)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017