使用Merapi来在AIR和Java中通信
Merapi是一个用于Java和AIR之间通信的桥接库。通过它可以极大的扩展AIR在本地的执行能力,当然前提是客户端不仅装有AIR运行时虚拟机,还需要安装有Java虚拟机。Merapi通过Socket来通信,使用Adobe的AMF作为数据传输格式。下面看看如何在Flash Builder中创建一个基于Adobe AIR的桌面软件。
在Java和ActionScript两端都存在一名为Bridge的类,它是一个Singleton,用来注册消息类型和发送消息。在这个例子中,AIR向Java端发送一个名为”flashEvent”的消息,消息内容是一个Dictionary实例;并且监听名为”javaEvent”的消息。
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()"> <mx:Script> <![CDATA[ import demo.JavaMessageHandler; import demo.SerializeMessageHandler; import merapi.Bridge; import merapi.messages.Message; import merapi.error.MerapiErrorMessage; private function initApp():void{ //register a error handler new SerializeMessageHandler(); //send a message var message:Message=new Message(); message.type="flashEvent"; var data:Dictionary=new Dictionary(); data["name"]="colorhook"; message.data=data; message.send(); //register a message handler Bridge.getInstance().registerMessageHandler("javaEvent", new JavaMessageHandler()); } ]]> </mx:Script> </mx:WindowedApplication>
CoreErrorHandler继承自EventDispatcher,实现了IMessageHandler接口,它在构造函数中就集成了错误处理。所以不需要显示的在Bridge中注册,而是构造一个实例就行了。SerializeMessageHandler继承自CoreErrorHandler,用来处理全局错误。
package demo{ import merapi.handlers.mxml.CoreErrorHandler; import mx.rpc.events.ResultEvent; public class SerializeMessageHandler extends CoreErrorHandler{ public function SerializeMessageHandler(type:String=null){ super(type); this.addEventListener(ResultEvent.RESULT,onMessageResult); } private function onMessageResult(event:ResultEvent):void{ trace("SerializeMessageHandler:",event); } } }
JavaMessageHandler实现了接口IMessageHandler,并在handleMessage方法中输出从Java中返回的数据。
package demo{ import merapi.handlers.IMessageHandler; import merapi.messages.IMessage; public class JavaMessageHandler implements IMessageHandler{ public function handleMessage(message:IMessage):void{ trace(message.type); trace(message.data); } } }
编译运行会发现控制台输出SerializeMessageHandler中的trace信息,因为目前还没有开启Java端的ServerSocket。所以下面来启动一个Java程序。首先调用Bridge.open()来启动ServerSocket。然后监听名为”flashEvent”的消息。
package demo; import org.apache.log4j.Logger; import merapi.Bridge; public class Application { protected Logger logger=Logger.getLogger(Application.class); public Application(){ logger.info("Application start"); //open Bridge Bridge.open(); //register a message handler Bridge.getInstance().registerMessageHandler("flashEvent", new AIRMessageHandler()); } public static void main(String[] args){ new Application(); } }
在消息处理器AIRMessageHandler中,输出来自Flash的数据,AMF将ActionScript中的Dictionary映射为Java中的Map。接受到数据之后,我们再从Java中发出一个Message,该Message携带了一个List类型的数据,在Flash中,它会被映射成Array类型。
package demo; import java.util.*; import org.apache.log4j.Logger; import merapi.handlers.IMessageHandler; import merapi.messages.IMessage; import merapi.messages.Message; public class AIRMessageHandler implements IMessageHandler { protected Logger logger=Logger.getLogger(AIRMessageHandler.class); @Override public void handleMessage(IMessage message) { //handle message logger.info(message.getType()); Map<String,String> map=(Map<String, String>)message.getData(); logger.info(map.get("name")); //send a new message Message newMessage=new Message(); newMessage.setType("javaEvent"); List<String> list=new ArrayList<String>(); list.add("Flash Player"); list.add("AIR"); newMessage.setData(list); newMessage.send(); } }
Merapi在Java端用到了Spring, log4j和Adobe AMF相关包, 所以运行时要保证项目包含了这些jar包。可以从Merapi的Google Code中得到这些包。
AIR2的发布,让我们在AIR和Java通信方面有了新的选择: flerry。
flerry使用了AIR2的新特性NativeProcess,它直接创建了一个进程了执行Java程序。从其作者的blog上可以了解更多信息: http://www.riaspace.net/2010/01/flerry-flex-java-bridge-for-adobe-air-2-0/