Brew Mobile Platform + Flash Development 初探

brew mobile phone推出有一段时间了,在模拟器上也尝试了一点新的东西, 比如他的Flash开发就是亮点.虽然到现在我们没有拿到手机但是可以看得出,这个Flash开发还是非常强大的. 下面先转载一段brew mp上的关于环境搭建的部分内容.

 

This section explains the installation procedure for setting up a Brew MP Flash development environment using Adobe Flash.

For best results, install the following software in this order:

1. Operating System: Microsoft Windows XP or Vista

2. Microsoft .NET Framework 3.5 or greater

3. Adobe Flash CS3 Professional or greater 
 Note: You may purchase the retail version, or download the free trial version:

    a. Go to http://www.adobe.com/downloads

    b. Select your version of Adobe Flash Professional.

    c. Either create an account or use an existing account.

    d. Download and install the trial version of this tool application.

4. Adobe Extension Manager 
 Note: Must be installed to support the Brew MP SDK Flash Plugin, Adobe Flash Lite, and Adobe Mobile Client (AMC) development.

5. Brew MP SDK 
 Note: This may be installed anytime previous to this step.

6. Brew MP SDK Flash Plugin

    a. Run the Brew MP SDK Launcher tool: 
 Start > Programs > Qualcomm > Brew Mobile Platform SDK (rev number) > Launcher

    b. Click Setup tab.

    c. Click Flash Plugin Install link.

7. If you have an earlier version of the BREW SDK BTIL or Brew MP SDK Connect installed, then uninstall them in Windows Add/Remove Programs.

8. Brew MP Connect
    Note: This is necessary for installing Brew MP applications on a Brew MP device.

    a. Run the Brew MP SDK Launcher tool:
    Start > Programs > Qualcomm > Brew Mobile Platform SDK (rev number) > Launcher

    b. Click Setup tab.

    c. Click Connect Install link. 

Note: See Brew MP Flash Application Primer for additional details on these pre-requisites.

 

前面的废话说完之后我们来看看Flash在这里是以一种怎样的姿态出现的.

我们知道首先在brew mp中,实际上是有IFlashPlayer这样的高级的接口了. 所以如果你以native code写出来程序作为主程序的话,可以在其中播放一段flash. 但是更厉害的事,你可以直接将Flash作为你的主程序. 下面张图说明了Flash Framework的流程:

Brew Mobile Platform + Flash Development 初探_第1张图片

 

我们可以找到brew mp SDK的samplecode目录,里面有一个flash_extensionapp的应用程序,可以看到.就像上面的图所描述的.这里有.dll, .swf,.ini. 他满足一个flash应用程序在模拟器上运行需要的元素.

如果我们运行这个应用程序的话就会发现.这是一个简单的页面. 有个start和stop的button.

Brew Mobile Platform + Flash Development 初探_第2张图片

如果运行的话开起来也平平无奇.但是其中却蕴含深意.因为这里的Start实际上就是调用了我们熟悉的BREW API ISHLL_SetTimer的方法, 类似的Stop也调用了ISHELL_STopTimer的方法. 但是等等. 这里是一个Flash的程序. 他怎么能调用brew api的接口呢?

这就是我要说的他很强大的地方, 在Brew MP中,引入了一个叫做ActionScript Extension的东东. 不要被这个名字误会了. 这个不是用Flash写的ActionScript的扩展,实际上这是一个用native code (C语言)写的DLL. 你可以写一个或几个这样的DLL.这是一个用来链接native code 和 ActionScript之间的桥梁. ActionScript通过ActionScript Extension提供的接口, 原则上可以调用任何的brew mp native API.这样就使得Flash Application比Brew native application显得更为强大了. 至少理论上是这样的.

下面我们具体看看这里是怎么完成调用的, 如果我们打开flash_extensionapp文件夹下面的 .as 文件的话我们可以看到这样类似的代码

// Guard against recreating the sample extension and the handler object if(undefined == sample) { sample = new com_qualcomm_asesample(); handler = new Object(); } // initialize dynamic text txtTimer = "0"; var count = 0; var running = 0; // start a BREW timer function startTimer() { running = 1; sample.startTimer(100, handler, "onTimer"); } // stop timer function stopTimer() { sample.stopTimer(); count = 0; running = 0; }

首先这里创建了sample的实例,这是一个asesample的实例, 这个实例在哪里呢? 这个实例就是flash_extension.如果我们打开samplecode下面flash_extension工程的话就会发现里面cif中的描述:


SysRsc {
    type = 0x1078f14, --AEEIID_IASExtension
    id   = "asextension/com_qualcomm_asesample",
    data = AEECLSID_FLASHEXT
 }

 

继续,我们看到了startTimer和stopTimer. 这两个接口调用了sample的两个成员函数, startTimer和stopTimer.这个调用是怎么发生的呢? 我在看到flash_extension的工程里面有这么一个函数:

/* interface method */ static AEEResult ASESample_CallMethod(IASExtension *pi, IASObject *piObj, IASArgs *piArgs, IASVar *piVar, const char *pszMethod) { ASESample *me = ASESampleFromIASExtension(pi); boolean bResult; if (0 == STRICMP(pszMethod, "startTimer")) { bResult = ASESample_StartTimer(me, piArgs); } else if (0 == STRICMP(pszMethod, "stopTimer")) { bResult = ASESample_StopTimer(me); } else if (0 == STRICMP(pszMethod, "postURL")) { bResult = ASESample_PostURL(me, piArgs, 0); } else if (0 == STRICMP(pszMethod, "browseURL")) { bResult = ASESample_PostURL(me, piArgs, 1); } else if (0 == STRICMP(pszMethod, "receiveURL")) { bResult = ASESample_ReceiveURL(me, piArgs); } else { IASVar_SetToUndefined(piVar); return AEE_EBADITEM; } IASVar_SetToBoolean(piVar, bResult); return AEE_SUCCESS; }

这下一下子明白了. 实际上的调用关系就是ActionScript=> ActionScript VM=>ActionScript Extension.ActionScript VM根据这边注册的IIASExtension的实例找到这个ASESample_CallMethod的方法来完成调用. 可以看到具体要调用那个函数通过pszMethod这个字段表现了出来.这个需要extension里面来做匹配的解析. 这样的流程就比较清晰了. (至于如何具体写一个extension的细节就不在这里展开了, Qualcomm的推荐是copy修改这个flash_extension的例子来做).

说完这个调用, 那只是Flash可以操纵native code 那Native code 如何通知Flash呢? 或者说如何调用Flash里面的函数呢? 我们注意到在.as文件里面StartTimer调用的时候有几个参数 sample.startTimer(100, handler, "onTimer");

答案就在这几个参数里面, onTimer在这里就是一个callback函数, 我们可以看到这个函数的原型:

// timer callback function
handler.onTimer = function()
{
    if (running) {
        txtTimer = String(++count);
        startTimer();
    }
}

类似的, 我们在回到flash_extension里面来看, 我们注意到了这样的实现:

//////////////////////////////////////////////////////////////////////////////// // extension methods static void ASESample_TimerFired(void *pv) { ASESample *me = (ASESample*)pv; IASObject_CallMethod(me->piObjTimer, me->pszMethodTimer, 0); IQI_RELEASEIF(me->piObjTimer); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Extension method - startTimer Usage: shell.startTimer(timeMs, handlerObj, methodName) Parameters: timeMs <number> Time in milliseconds of timer delay. handlerObj <object> Object that will process the function result. methodName <string> Name of the method on handlerObj that will process the function result. Must conform to the function prototype: <onTimerFired> Handler: <onTimerFired>() This handler is invoked when timer has fired. Handler Parameters: None. */ static boolean ASESample_StartTimer(ASESample *me, IASArgs *piArgs) { IASObject *piObj = 0; char aBuffer[64]; AEEResult nErr; int nValue, cbReq; FREEIF(me->pszMethodTimer); IQI_RELEASEIF(me->piObjTimer); nErr = IASArgs_GetAsInteger(piArgs, 0, &nValue); if (AEE_SUCCESS != nErr) { goto bail; } nErr = IASArgs_GetAsObject(piArgs, 1, &piObj); if (AEE_SUCCESS != nErr) { goto bail; } nErr = IASArgs_GetAsString(piArgs, 2, aBuffer, sizeof(aBuffer), &cbReq); if (AEE_SUCCESS != nErr) { goto bail; } // save method name nErr = ERR_STRDUP((const char*)aBuffer, (char**)&me->pszMethodTimer); if (AEE_SUCCESS != nErr) { goto bail; } // save handler object me->piObjTimer = piObj; IASObject_AddRef(me->piObjTimer); nErr = ISHELL_SetTimer(me->piShell, (int32)nValue, ASESample_TimerFired, me); bail: IQI_RELEASEIF(piObj); return (AEE_SUCCESS == nErr) ? 1 : 0; // 1 means SetTimer succeeded }

实际上里面的回调是通过IASObject_CallMethod来完成的.我们注意到这里的IASArgs *piArgs指代的就是startTimer时候的参数列表, 可以看到, 这里通过IASArgs_GetAsString接口拿到了第三个参数(实际上就是onTimer). 然后在timer到了之后就通过 IASObject_CallMethod(me->piObjTimer, me->pszMethodTimer, 0);来通知Flash.

 

总结一下的话就是Flash在Brew MP平台下可以调用Brew MP的native API来扩展功能. 但是必须通过ActionScript来完成.ActionScript通过两个主要的接口来完成信息交互. Flash用IASExtension_CallMethod来调用brew的接口, brew用IASObject_CallMethod来调用Flash的接口.这次还只是浅尝辄止性的调研. 如果要深入开发的话, 还是很多更细致的问题, 比如如果我在Brew代码里面用IDisplay来画页面, 那这个时候到底是谁在控制屏幕呢?到底是同步异步呢?很糊涂吧.. 而且有的应用用ActionScript的camera模块是不行的, 需要用native code的ICamera. 这个时候实时性要求很高, 如何和Flash的UI相结合呢?所以总的来说, 至少Flash的Brew MP解决方案看上去很美,但是其下又有多少暗涌呢,恐怕还没有人知道...

 

 

 

你可能感兴趣的:(Flash,mobile,brew,Adobe,actionscript,extension)