AIR 2.0 有很多令人期待和振奋的功能,使得AIR向成熟的桌面应用程序开发环境又进了一大步。上一篇文章里介绍了ServerSocket的用法,这篇教程中将向大家介绍NativeProcess,在AIR2.0中我们可以使用程序默认的打开方式直接打开一个外部的应用程序 (file.openWithDefaultApplication()) 或者 通过今天要讲的启动进程方式运行一个程序。
AIR与本地应用程序的交互是AIR 2.0的一个重要更新,这个功能的实现可以帮助我们做到在AIR 1.5时代很难完成的事情,比如我在项目中就需要操作一些硬件,但AIR不能直接操作端口,所以只能借助其他的小程序来实现,现在我们就可以很容易的操作这些小程序以达到操作硬件的目的,而Flex (AIR)与JAVA的结合很早就已经开始了,但由于早期AIR的局限性,想要把JAVA直接部署在客户端还是比较麻烦的事情,但是从AIR2.0开始我们不用担心了。现在我们用很简单的方式就可以在AIR程序中集成TOMCAT, 一次性的将后台与AIR部署到客户端。
程序的原版(Flash Builder 4版)同样是从http://coenraets.org/获得,有兴趣的朋友可以关注这个博客。我的例子仍然使用FLEX 3.
Demo过程
- 下载安装 AIR 2.0 beta runtime.
- 下载AIRAppWithEmbeddedTomcat..exe 或者 AIRAppWithEmbeddedTomcat.dmg (NativeProcess 必须在程序发布为相应平台的应用程序后才可以使用,发布的方法这里就不介绍了,可以参看http://help.adobe.com/en_US/FlashPlatform/develop/air/building_apps/WS789ea67d3e73a8b22388411123785d839c-8000.html)
- 安装运行AIRAppWithEmbeddedTomcat.exe, 修改JAVA_HOME,如果默认的路径不对
- 点击 “启动” 可以开启TOMCAT(端口是8080)。在JSP实例和RemoteObject实例中可以看见加载JSP页面和使用RemoteObject获取数据的测试。
控制台

JSP 加载测试

RemoteObject 测试

源代码
<?xml version="1.0" encoding="utf-8"?> <!--www.flextheworld.com--> <mx:WindowedApplication applicationComplete="init()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" height="600" width="800" > <mx:Script> <![CDATA[ import mx.controls.Alert; //用于启动和停止Tomcat的进程 private var startTomcatProcess:NativeProcess; private var stopTomcatProcess:NativeProcess; private var tomcatHomeDir:File; public function init():void { if (!NativeProcess.isSupported) { Alert.show("不支持进程控制,请先将程序发布为当前操作系统应用程序"); } //如果tomcat不存在,重新复制到app store文件夹 tomcatHomeDir = File.applicationStorageDirectory.resolvePath("tomcat"); if (!tomcatHomeDir.exists) { var tomcatOriginalDir:File = File.applicationDirectory.resolvePath("tomcat"); trace("Copying tomcat to appStorageDirectory..."); tomcatOriginalDir.copyTo(tomcatHomeDir); var f:File; f.openWithDefaultApplication() } tomcatHome.text = tomcatHomeDir.nativePath; // 读取保存的配置(第一次运行以后生成) var xml:XML = readConfig(); if (xml != null) { javaHome.text = xml.javaHome; return; } // 如果第一次使用,设置默认Path if (Capabilities.os.toLowerCase().indexOf("win") > -1) { // 默认的JAVA_HOME (windows) javaHome.text = "C:\\Program Files\\Java\\jdk1.6.0"; } else if (Capabilities.os.toLowerCase().indexOf("mac") > -1) { // 默认的JAVA_HOME (Mac) javaHome.text = "/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0"; } } public function startTomcat():void { // 将本次的JAVA_HOMR写入配置文件 writeConfig(); log.text = "Starting Tomcat..." + File.lineEnding; startTomcatProcess = new NativeProcess(); execute(startTomcatProcess, "start"); } public function stopTomcat():void { log.text = "Stopping Tomcat..." + File.lineEnding; stopTomcatProcess = new NativeProcess(); execute(startTomcatProcess, "stop"); } public function execute(process:NativeProcess, arg:String):void { // 先获取JVM var file:File = new File(javaHome.text); if (Capabilities.os.toLowerCase().indexOf("win") > -1) { file = file.resolvePath("bin/javaw.exe"); } else { file = file.resolvePath("Home/bin/java"); } // 启动TOMCAT try { var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); nativeProcessStartupInfo.executable = file; nativeProcessStartupInfo.workingDirectory = tomcatHomeDir.resolvePath("bin"); var processArgs:Vector.<String> = new Vector.<String>(); processArgs[0] = "-Dcatalina.home="+tomcatHomeDir.nativePath; processArgs[1] = "-classpath"; processArgs[2] = tomcatHomeDir.resolvePath("bin/bootstrap.jar").nativePath; processArgs[3] = "org.apache.catalina.startup.Bootstrap"; processArgs[4] = arg; nativeProcessStartupInfo.arguments = processArgs; startTomcatProcess = new NativeProcess(); startTomcatProcess.start(nativeProcessStartupInfo); startTomcatProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, outputDataHandler); startTomcatProcess.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, errorOutputDataHandler); } catch (e:Error) { Alert.show(e.message, "Error"); } } public function outputDataHandler(event:ProgressEvent):void { var process:NativeProcess = event.target as NativeProcess; var data:String = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable); log.text += data; } public function errorOutputDataHandler(event:ProgressEvent):void { var process:NativeProcess = event.target as NativeProcess; var data:String = process.standardError.readUTFBytes(startTomcatProcess.standardError.bytesAvailable); log.text += data; } private function readConfig():XML { var file:File = File.applicationStorageDirectory.resolvePath("config.xml"); if (file.exists) { var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.READ); var xml:XML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable)); fileStream.close(); return xml; } else { return null; } } private function writeConfig():void { var xml:String = '<?xml version="1.0" encoding="utf-8"?>' + File.lineEnding; xml += "<config>" + File.lineEnding; xml += "<javaHome>" + javaHome.text + "</javaHome>" + File.lineEnding; xml += "<tomcatHome>" + tomcatHome.text + "</tomcatHome>" + File.lineEnding; xml += "</config>" + File.lineEnding; var file:File = File.applicationStorageDirectory.resolvePath("config.xml"); var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.WRITE); fileStream.writeUTFBytes(xml); fileStream.close(); } ]]> </mx:Script> <mx:RemoteObject id="srv" destination="contacts" endpoint="http://localhost:8080/messagebroker/amf" /> <mx:TabNavigator width="100%" height="100%"> <mx:VBox width="100%" height="100%" label="控制台" paddingLeft="8" paddingRight="8" paddingBottom="8"> <mx:Form width="100%"> <mx:FormItem label="Java Home" width="100%"> <mx:TextInput id="javaHome" width="100%"/> </mx:FormItem> <mx:FormItem label="Tomcat Home (嵌入的TOMCAT)" width="100%"> <mx:TextInput id="tomcatHome" width="100%" enabled="false"/> </mx:FormItem> </mx:Form> <mx:HBox> <mx:Button label="启动" click="startTomcat()"/> <mx:Button label="停止" click="stopTomcat()"/> <mx:Button label="清除信息" click="log.text=''"/> </mx:HBox> <mx:TextArea id="log" width="100%" height="100%"/> </mx:VBox> <mx:VBox label="嵌入的JSP实例" paddingLeft="8" paddingRight="8" paddingBottom="8"> <mx:HTML id="html" width="100%" height="100%"/> <mx:Button label="读取JSP" click="html.location='http://localhost:8080'"/> </mx:VBox> <mx:VBox label="嵌入的RemoteObject实例" paddingLeft="8" paddingRight="8" paddingBottom="8"> <mx:DataGrid width="100%" height="100%" dataProvider="{srv.findAll.lastResult}"> <mx:columns> <mx:DataGridColumn dataField="id" headerText="Id"/> <mx:DataGridColumn dataField="firstName" headerText="First Name"/> <mx:DataGridColumn dataField="lastName" headerText="Last Name"/> <mx:DataGridColumn dataField="city" headerText="City"/> </mx:columns> </mx:DataGrid> <mx:Button label="获取数据" click="srv.findAll()"/> </mx:VBox> </mx:TabNavigator> </mx:WindowedApplication> |
下载
源代码: AIRAppWithEmbeddedTomcat.zip (72)
windows demo: AIRAppWithEmbeddedTomcat.exe (56)
Mac Demo: AIRAppWithEmbeddedTomcat.dmg (40)

win7下载
Reply