You actually can get 30fps to 50fps in Adobe Air with very complex Flash vector animations.
What not to do:
Don't use the pre-made "Cache as bitmap" checkbox for anything animated. This is a great feature when applied to static vector images, as it converts it to a static bitmap. If the animation is animated in any way other than translating the movie clip on x or y axis, your animation will actually be SLOWER with cache as bitmap turned on.
Don't do blitting. Blitting can make games blazing fast in Flash, but on Adobe air it makes them slower. What you want is a bitmap Object placed on the stage, not a bitmapData object being blitted onto the stage.
So, what you CAN do to is grab a swf or Movieclip, and run though every frame of the object and convert each frame to a bitmap. Then, save each bitmap into an array. Then, to play the animation, retrieve the bitmaps from the array and place them sequentially on the stage. In my tests, I am able to run a full screen, 24 frame animation on an Android tablet at over 40fps.
Code sample follows. It will cache the bitmaps slowly, finish, and then immediately start playing at a much higher rate. If desired, you an hide the animation while it caches. Clear the array to free up memory when you don't need the animation anymore.
package scripts.animation{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Stage;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.*;
import flash.events.Event;
public class spriteSheetMaker extends MovieClip {
private var pWidth:int=0;
private var pHeight:int=0;
private var regX:int=0;
private var regY:int=0;
private var swfObj:MovieClip = null;
private var pFrame:int=0;
private var pFrames:int=0;
private var pSheetArray:Array=[];
private var pSheetInfo:Array=[];
private var pAnimating:Boolean = false;
private var pAnimationCycle:int = 0;
//-------------------------------------------------------
//-------------------------------------------------------
//init
//-------------------------------------------------------
//-------------------------------------------------------
public function spriteSheetMaker ():void {
startGrab();
}
//-------------------------------------------------------
//-------------------------------------------------------
//swf is loaded, find out how many frames are in, dimentions etc, and start animation
//-------------------------------------------------------
//-------------------------------------------------------
public function startGrab ():void {
swfObj=this.animation;
swfObj.x = 0;
//swfObj.y = 0;
pFrames=swfObj.totalFrames;
pFrame=0;
pSheetInfo=[this.name,pWidth,pHeight];
pSheetArray.push (pSheetInfo);
pAnimating = false;
this.addEventListener (Event.ENTER_FRAME,cycleSwfAnim);
}
//-------------------------------------------------------
//-------------------------------------------------------
//load the next frame of the animation and convert it
//-------------------------------------------------------
//-------------------------------------------------------
private function cycleSwfAnim (event:Event):void {
pFrame++;
if (pFrame < pFrames + 2) {
swfObj.gotoAndStop (pFrame);
grabBitmap ();
} else {
stopGrab ();
}
}
//
private function stopGrab():void{
this.removeEventListener (Event.ENTER_FRAME,cycleSwfAnim);
trace("Sheet = " + pSheetArray);
swfObj.parent.removeChild(swfObj);
swfObj=null;
startAnimationPlayback();
}
//-------------------------------------------------------
//-------------------------------------------------------
//Convert fram (vector, bitmap, whatever is on the frame) into a bitmadata object
//-------------------------------------------------------
//-------------------------------------------------------
private function grabBitmap ():void {
pWidth=this.width;
pHeight=this.height;
var bmd:BitmapData=new BitmapData(pWidth,pHeight,true,0x00FFFFFF);
bmd.draw (swfObj);
var bm:Bitmap = new Bitmap();
bm.bitmapData = bmd;
pSheetArray.push (bm);
}
//-------------------------------------------------------
//-------------------------------------------------------
//Play animation
//-------------------------------------------------------
//-------------------------------------------------------
private function startAnimationPlayback():void{
this.addEventListener (Event.ENTER_FRAME,animate);
pFrame =0;
}
//
private function animate(event:Event):void{
pFrame++;
if (pFrame>pSheetArray.length){
pFrame = 1;
}
var bm:Bitmap = pSheetArray[pFrame];
if (bm != null){
if (this.numChildren>0){
this.removeChildAt(0);
}
this.addChild(bm);
}
}
}
}