实验:结合Merapi增强Flash Player的功能
在RIAMeeting之前的一篇文章中介绍过Merapi,如果你还不太了解,请点击这里。
简单说来,Merapi就是基于Socket沟通Flex/Flash/AIR项目与Java的桥梁,这样我们就可以通过Java扩展原先Flash平台所不具备的功能,比如与系统深层次的整合,调取电脑外设等等,在上面那篇文章中对Merapi的工作机制有详细的介绍,这里不再阐述。
现在我们通过一个例子,来直观的体验一下Merapi所带来的便捷(目前仍是Beta版,还是有这样那样的问题,对Byte的支持似乎也不够好,字符串完全没有问题)。这个例子里我们直接使用Flex建立的Web项目来进行(当然你也可以使用AIR),通过一个Java应用截取系统的屏幕,并返回给Flex端显示。
步骤一:配置
首先是工具,因为要写两个项目(Flex项目和Java项目),准备好你喜欢的IDE吧,我这里是Flash Builder和MyEclipse。
然后要下载Merapi的类库,下载地址在:
http://code.google.com/p/merapi/source/browse/#svn/binaries/merapi-core-0.1.8-beta
注意还要下载Java项目依赖的Jar包,地址在:
http://code.google.com/p/merapi/source/browse/#svn/trunk/java/merapi-core/libs%3Fstate%3Dclosed
步骤二:建立Java项目
建立一个Java项目,将之前下载的Jar包加入到Build Path。
首先建立一个ScreenShot的Java类,声明一个方法,返回参数指定的屏幕区域的截图(转换为字节)。
public class ScreenShot { File f = new File("f"); Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture(screenRectangle); ImageIO.write(image, "png", f); FileInputStream fis=new FileInputStream (f); byte[] resultBytes = new byte[len]; fis.read(resultBytes); return resultBytes; } }
然后建立一个QuestionMessage类,它包含呼叫时的问题(question)和答案(answer)。
package messages; import merapi.messages.Message; public class QuestionMessage extends Message { public QuestionMessage() { // TODO Auto-generated constructor stub } public byte[] getAnswer() { return __answer; } public void setAnswer( byte[] val ) { __answer = val; } private byte[] __answer = null; }
还需要声明一个消息处理器,处理返回的Message。
package handler; import tool.ScreenShot; import merapi.handlers.MessageHandler; import messages.QuestionMessage; import merapi.messages.IMessage; public class QuestionHandler extends MessageHandler { public QuestionHandler() { super(QuestionMessage.ASK_IT); } public void handleMessage( IMessage message ) { if ( message instanceof QuestionMessage ) { QuestionMessage qMessage = ( QuestionMessage ) message; ScreenShot ss = new ScreenShot(); pos = qMessage.getQuestion().split(","); try { qMessage.setAnswer(ss.captureScreen(Integer.parseInt(pos[0]), Integer.parseInt(pos[1]), Integer.parseInt(pos[2]), Integer.parseInt(pos[3]))); //qMessage.setAnswer("answer:"+qMessage.getQuestion()); qMessage.send(); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
最后在主类的入口方法里启动handler。
import merapi.Bridge; import handler.QuestionHandler; public class Main { Bridge.open(); new QuestionHandler(); } }
至此Java项目编写完毕,运行无错,即可转入Flex项目建立。
步骤三:建立Flex项目
建立一个Flex项目,将下载的SWC库加入到libs目录。和Java项目对应,也要声明一个QuestionMessage类,注意这个类跟java中的类相对应。
package messages { import merapi.messages.Message; [RemoteClass( alias="messages.QuestionMessage" )] public class QuestionMessage extends Message { public function QuestionMessage() { super(ASK_IT); } } }
然后在主MXML文件中,呼叫Merapi,并处理返回的信息。
<?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:merapiproject="http://merapiproject.net/2009" creationComplete="application1_creationCompleteHandler(event)" xmlns:mx="library://ns.adobe.com/flex/mx" width="600" height="500"> <fx:Declarations> <merapiproject:MessageHandler id="questionHandler" type="{ QuestionMessage.ASK_IT }" result="handleResult(event)" /> </fx:Declarations> <fx:Script> <![CDATA[ import merapi.messages.IMessage; import merapi.messages.Message; import messages.*; import mx.events.FlexEvent; import mx.rpc.events.ResultEvent; private var q:QuestionMessage = new QuestionMessage(); private function askIt():void{ q.question = mouseX+","+mouseY+","+600+","+500; q.send(); sendMode = true; } private function handleResult(e:ResultEvent):void{ var message:QuestionMessage = e.result as QuestionMessage; if(message.question != q.question) return; trace(message.question); if(imgLoader!=null) imgLoader.unloadAndStop(); imgLoader.loadBytes(message.answer); uic.addChild(imgLoader); sendMode = false; } protected function application1_creationCompleteHandler(event:FlexEvent):void { //uic.addChild(imgLoader); uic.graphics.beginFill(0x000000,1); uic.graphics.drawRect(0,0,600,500); uic.graphics.endFill(); } if(!sendMode) askIt(); } ]]> </fx:Script> <mx:UIComponent id="uic" x="0" y="0"/> <s:Label x="23" y="23" text="点击获取屏幕截图" color="#FFFC00"/> </s:Application>
至此Flex项目也编写完毕。注意两边的数据传输是图片数据的字节数组(ByteArray),在笔者的项目中有个Bug,即再次生成图片的结果没有返回,而字符串则没有问题,猜测是Merapi的Bug,有待解决。
步骤四:运行
首先将我们刚才建立的Java项目Run起来,然后Run Flex项目,在浏览器显示的Flash界面上点击鼠标,不出意外的话,可以看到自己屏幕的截图。
图1:运行效果,点击看大图
谨以此例抛砖引玉,欢迎大家讨论!


.gif)
.gif)




.gif)
在flex4上使用似乎有些问题
在flex4上使用似乎有些问题
很感兴趣,能不能对比下其他类似技术?
有没有类似的别的技术?
搬到手机上如何?
Merapi能在手机上运行么?比如Android。
发表新评论