实验:结合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类,声明一个方法,返回参数指定的屏幕区域的截图(转换为字节)。

  1. public class ScreenShot {
  2.  
  3. public byte[] captureScreen(int x, int y, int w, int h) throws Exception {
  4. File f = new File("f");
  5. Rectangle screenRectangle = new Rectangle(x, y, w, h);
  6. Robot robot = new Robot();
  7. BufferedImage image = robot.createScreenCapture(screenRectangle);
  8. ImageIO.write(image, "png", f);
  9. FileInputStream fis=new FileInputStream (f);
  10. int len=fis.available();
  11. byte[] resultBytes = new byte[len];
  12. fis.read(resultBytes);
  13. System.out.println(x+","+y);
  14. return resultBytes;
  15. }
  16.  
  17. }

然后建立一个QuestionMessage类,它包含呼叫时的问题(question)和答案(answer)。

  1. package messages;
  2.  
  3. import merapi.messages.Message;
  4.  
  5. public class QuestionMessage extends Message {
  6.  
  7. public static final String ASK_IT = "magicQuestion";
  8.  
  9. public QuestionMessage() {
  10. // TODO Auto-generated constructor stub
  11. }
  12.  
  13. public String getQuestion() { return __question; }
  14. public void setQuestion( String val ) { __question = val; }
  15. public byte[] getAnswer() { return __answer; }
  16. public void setAnswer( byte[] val ) { __answer = val; }
  17. private String __question = null;
  18. private byte[] __answer = null;
  19.  
  20. }

还需要声明一个消息处理器,处理返回的Message。

  1. package handler;
  2.  
  3. import tool.ScreenShot;
  4. import merapi.handlers.MessageHandler;
  5. import messages.QuestionMessage;
  6. import merapi.messages.IMessage;
  7.  
  8. public class QuestionHandler extends MessageHandler {
  9.  
  10. String[] pos = null;
  11.  
  12. public QuestionHandler() {
  13. super(QuestionMessage.ASK_IT);
  14. }
  15.  
  16. public void handleMessage( IMessage message ) {
  17. if ( message instanceof QuestionMessage ) {
  18. QuestionMessage qMessage = ( QuestionMessage ) message;
  19. ScreenShot ss = new ScreenShot();
  20. pos = qMessage.getQuestion().split(",");
  21. try {
  22. qMessage.setAnswer(ss.captureScreen(Integer.parseInt(pos[0]), Integer.parseInt(pos[1]), Integer.parseInt(pos[2]), Integer.parseInt(pos[3])));
  23. //qMessage.setAnswer("answer:"+qMessage.getQuestion());
  24. qMessage.send();
  25. } catch (NumberFormatException e) {
  26. // TODO Auto-generated catch block
  27. e.printStackTrace();
  28. } catch (Exception e) {
  29. // TODO Auto-generated catch block
  30. e.printStackTrace();
  31. }
  32. }
  33. }
  34.  
  35. }

最后在主类的入口方法里启动handler。

  1. import merapi.Bridge;
  2. import handler.QuestionHandler;
  3.  
  4. public class Main {
  5. public static void main( String[] args ) {
  6. Bridge.open();
  7. new QuestionHandler();
  8. System.out.println("Main open");
  9. }
  10. }

至此Java项目编写完毕,运行无错,即可转入Flex项目建立。

步骤三:建立Flex项目

建立一个Flex项目,将下载的SWC库加入到libs目录。和Java项目对应,也要声明一个QuestionMessage类,注意这个类跟java中的类相对应。

  1. package messages
  2. {
  3. import flash.utils.ByteArray;
  4.  
  5. import merapi.messages.Message;
  6.  
  7. [RemoteClass( alias="messages.QuestionMessage" )]
  8.  
  9. public class QuestionMessage extends Message
  10. {
  11. public static const ASK_IT : String = "magicQuestion";
  12. public var question : String = null;
  13. public var answer : ByteArray = null;
  14.  
  15. public function QuestionMessage()
  16. {
  17. super(ASK_IT);
  18. }
  19. }
  20. }

然后在主MXML文件中,呼叫Merapi,并处理返回的信息。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3. xmlns:s="library://ns.adobe.com/flex/spark"
  4. xmlns:merapiproject="http://merapiproject.net/2009"
  5. creationComplete="application1_creationCompleteHandler(event)"
  6. xmlns:mx="library://ns.adobe.com/flex/mx" width="600" height="500">
  7. <fx:Declarations>
  8. <merapiproject:MessageHandler id="questionHandler" type="{ QuestionMessage.ASK_IT }" result="handleResult(event)" />
  9. </fx:Declarations>
  10.  
  11. <fx:Script>
  12. <![CDATA[
  13. import merapi.messages.IMessage;
  14. import merapi.messages.Message;
  15.  
  16. import messages.*;
  17.  
  18. import mx.events.FlexEvent;
  19. import mx.rpc.events.ResultEvent;
  20.  
  21. private var imgLoader:Loader;
  22. private var sendMode:Boolean = false;
  23. private var q:QuestionMessage = new QuestionMessage();
  24.  
  25. private function askIt():void{
  26. q.question = mouseX+","+mouseY+","+600+","+500;
  27. q.send();
  28. sendMode = true;
  29. }
  30.  
  31. private function handleResult(e:ResultEvent):void{
  32. var message:QuestionMessage = e.result as QuestionMessage;
  33. if(message.question != q.question) return;
  34. trace(message.question);
  35. if(imgLoader!=null) imgLoader.unloadAndStop();
  36. imgLoader = new Loader();
  37. imgLoader.loadBytes(message.answer);
  38. uic.addChild(imgLoader);
  39. sendMode = false;
  40. }
  41.  
  42. protected function application1_creationCompleteHandler(event:FlexEvent):void
  43. {
  44. //uic.addChild(imgLoader);
  45. addEventListener(MouseEvent.MOUSE_DOWN,moveHandler);
  46. uic.graphics.beginFill(0x000000,1);
  47. uic.graphics.drawRect(0,0,600,500);
  48. uic.graphics.endFill();
  49. }
  50.  
  51. private function moveHandler(e:MouseEvent):void {
  52. if(!sendMode) askIt();
  53. }
  54.  
  55. ]]>
  56. </fx:Script>
  57.  
  58. <mx:UIComponent id="uic" x="0" y="0"/>
  59. <s:Label x="23" y="23" text="点击获取屏幕截图" color="#FFFC00"/>
  60.  
  61. </s:Application>

至此Flex项目也编写完毕。注意两边的数据传输是图片数据的字节数组(ByteArray),在笔者的项目中有个Bug,即再次生成图片的结果没有返回,而字符串则没有问题,猜测是Merapi的Bug,有待解决。

步骤四:运行

首先将我们刚才建立的Java项目Run起来,然后Run Flex项目,在浏览器显示的Flash界面上点击鼠标,不出意外的话,可以看到自己屏幕的截图。

点击看大图

图1:运行效果,点击看大图

谨以此例抛砖引玉,欢迎大家讨论!

riadevID: 
相关主题: 
您给予的分值: None 平均分: 10 (1 vote)

在flex4上使用似乎有些问题

在flex4上使用似乎有些问题

很感兴趣,能不能对比下其他类似技术?

有没有类似的别的技术?

搬到手机上如何?

Merapi能在手机上运行么?比如Android。

发表新评论

  • 网页地址和电子邮件地址将会被自动转换为链接。
  • 行和段被自动切分。
  • 您可以使用下面的标签来高亮显示您的评论内容: <code>, <blockcode>. 可以使用"[foo]".旁边显示标签样式 "<foo>" PHP代码可以用这样的区块来包含<?php ... ?> or <% ... %>

更多格式化选项信息

验证区域
系统验证:请回答下面的问题