AIR2.0入门教程[三]:与本地进程的数据通讯

在前两篇文章中,我们了解了AIR2.0Beta带来的新特性,以及AIR2.0中的拖拽增强,现在我们来看AIR2.0另一个非常有用的新特性:可以启动本地进程并与本地进程进行数据通讯。

了解NativeProcess

在AIR2中,我们可以打包一个AIR应用为本地安装文件,比如在Windows下面是.exe,在Mac系统下是.dmg,这样我们的AIR应用就具备了运行一个本地进程并与之交互的能力。要实现这个功能,需要使用NativeProcess类。这是AIR2中出现的一个新的类。

我们可以调用NativeProcess.isSupported,来判断我们的AIR应用是否支持运行本地进程,如果你的应用是以.air部署的,那么就会得到值为false。

要运行本地进程,我们需要创建一个NativeProcess类的实例,并调用它的start 方法来启动一个进程,与这个类配合工作的还有NativeProcessStartupInfo类,我们也要创建这个类的实例,并指定可运行的exe文件(windows下)。

在下面的例子中,我们还将讲解如何打包一个AIR应用为一个本地安装文件,并且了解如何使用标准的输入输出(STDIN和STDOUT)流来通讯。

如果你已经具备了一些C++语言的编程知识,那理解这篇文章就更容易一些。

本文涉及的源码下载:

  1. AIR项目源码下载

准备和编译C++应用

在这个示例中,我们会创建一个C++的程序文件,你可以使用VS或其它你熟悉的工具来编译这个类文件为exe文件,这个文件的代码部分很简单,就是执行从m到n的累加,然后将计算的结果通过标准输入输出返回。如果你不能编译也不必担心,这个例子的源码中已经包含了编译后的exe文件。

C++代码:

  1. #include <iostream>
  2. using namespace std;
  3. void main (void)
  4. {
  5. int a,b;
  6. int c=100;
  7. cin>>a>>b;
  8. for(int i=a;i<b;i++) {
  9. c+=i;
  10. }
  11. cout<<c<<endl;
  12. }

将编译后的exe文件保存好,一会儿会用到。

创建AIR应用

使用Flex Builder创建一个AIR项目,注意选择SDK为包含AIR2 SDK的版本(在第一篇文章中有介绍),然后打开AIR的配置XML文件,添加下面的一行:

<supportedProfiles>extendedDesktop</supportedProfiles>

这是必须的,否则你的AIR应用将无法执行本地进程。

然后用下面的代码替换掉你的主文件的代码,代码中我们调取C++来计算一个从m到n的累加计算,并提供了用AS3计算的机制,来做对比。当然,结果没有悬念,C++轻松胜出,我们可以从中启发一些想法,比如将AIR应用中计算复杂的一些工作交给本地进程来做,以获得更高的执行效率。请着重参考中间的进程调取部分(中文注释):

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init()" layout="absolute" width="356" height="347">
  3. <mx:Script>
  4. <![CDATA[
  5. import flash.events.MouseEvent;
  6. private var process:NativeProcess;
  7. [Bindable]
  8. private var resultData:String;
  9. [Bindable]
  10. private var cerData:String;
  11.  
  12. private var startDate:Date;
  13. private var endDate:Date;
  14.  
  15. public function init():void
  16. {
  17. if (NativeProcess.isSupported)//判断是否支持调取本地进程
  18. {
  19. launchEchoTest();
  20. }
  21. else
  22. {
  23. resultData = "NativeProcess not supported.";
  24. }
  25. }
  26. public function launchEchoTest():void//这个方法初始化的时候即执行,运行exe文件,等待输入参数
  27. {
  28. var file:File = File.applicationDirectory;//创建File对象
  29. file = file.resolvePath("NativeApps/Windows/bin/TestCCC.exe");//指向你的exe文件
  30.  
  31. var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();//创建进程信息对象
  32. nativeProcessStartupInfo.executable = file;//将file指定为可执行文件
  33.  
  34. process = new NativeProcess();//创建一个本地进程
  35. process.start(nativeProcessStartupInfo);//运行本地进程
  36. process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);//侦听进程的输出信息
  37. process.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, inputProgressListener);//侦听进程的输入信息
  38. }
  39. public function writeData():void
  40. {
  41. process.standardInput.writeUTFBytes(num1.text + "\n");//C++方法中需要的两个输入,从这里写入
  42. process.standardInput.writeUTFBytes(num2.text + "\n");
  43. }
  44. public function inputProgressListener(event:ProgressEvent):void
  45. {
  46. process.closeInput();//关闭输入
  47. }
  48. public function onOutputData(event:ProgressEvent):void
  49. {
  50. resultData = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable);//获取进程返回的数据
  51. endDate = new Date();
  52. cerData = endDate.time - startDate.time + "";//计算时间差值
  53. launchEchoTest();//再次启动进程,并等待输入
  54. }
  55.  
  56. protected function button1_clickHandler(event:MouseEvent):void
  57. {
  58. startDate = new Date();
  59. if(radiogroup1.selectedValue == 0) {
  60. trace("use c++");
  61. writeData();
  62. } else {
  63. trace("use as3");//使用AS3(AVM)来执行计算
  64. var a:uint = uint(num1.text);
  65. var b:uint = uint(num2.text);
  66. var c:uint = 0;
  67. for(var i:uint = a;i<b;i++) {
  68. c+=i;
  69. }
  70. resultData = c+"";
  71. endDate = new Date();
  72. cerData = endDate.time - startDate.time + "";
  73. }
  74.  
  75. }
  76.  
  77. ]]>
  78. </mx:Script>
  79. <mx:Panel width="336" height="317" layout="absolute" x="10" y="10" title="AIR结合C++实例">
  80. <mx:TabNavigator x="10" y="10" width="296" height="257">
  81. <mx:Canvas label="从m到n的累加计算测试" width="100%" height="100%">
  82. <mx:Form x="0" y="0" width="100%" height="100%">
  83. <mx:FormItem label="数字1">
  84. <mx:TextInput id="num1" text="1"/>
  85. </mx:FormItem>
  86. <mx:FormItem label="数字2">
  87. <mx:TextInput id="num2" text="100000000"/>
  88. </mx:FormItem>
  89. <mx:FormItem>
  90. <mx:RadioButtonGroup id="radiogroup1"/>
  91. <mx:RadioButton label="使用C++计算" value="0" groupName="radiogroup1" selected="true"/>
  92. <mx:RadioButton label="使用AS3计算" value="1" groupName="radiogroup1"/>
  93. <mx:Button label="执行累加计算" click="button1_clickHandler(event)"/>
  94. </mx:FormItem>
  95. <mx:FormItem label="结果">
  96. <mx:Label text="{resultData}" id="l1"/>
  97. </mx:FormItem>
  98. <mx:FormItem label="计算时间">
  99. <mx:Label text="{cerData}" id="l2"/>
  100. </mx:FormItem>
  101. </mx:Form>
  102. </mx:Canvas>
  103. </mx:TabNavigator>
  104. </mx:Panel>
  105. </mx:WindowedApplication>

然后将下载的源码解压,找到位于NativeApp/Windows/bin下面的exe文件,复制到你的项目目录中,并更改代码部分相应的位置定义。

编译项目,如果配置没有错误,会得到如下图所示的界面,你可以点击计算按钮,观测从C++返回的数据。然后点击AS3计算方式,做一下对比。

下面我们来把这个应用打包为本地安装文件。

打包为本地安装文件(EXE)

打包过程,请遵循下面的步骤:

  1. 首先需要配置你的电脑环境,选择“我的电脑”,点右键选择“属性”,然后找到高级设置里的环境变量,在系统变量的PATH部分,添加一行:C:\Program Files\Adobe\Adobe Flash Builder Beta 2\sdks\3.4.1\bin。注意这个路径应该包含了adt.exe的位置,请以自己电脑实际情况为准。
  2. 运行CMD,输入adt,按下回车,如果有帮助信息输入,则代表配置成功
  3. 将我们刚才创建的AIR项目打包为.air文件,最后会因为配置修改有个错误,忽略即可
  4. 执行CD命令,进入你要保存打包后exe文件的目录,然后输入adt -package -target native demo.exe e:/project/air/simple/bin/demo.air
  5. 以上请以自己的实际路径为准

End

riadevID: 
您给予的分值: None 平均分: 7.5 ( 6 票)

作者的exe貌似有错,

作者的exe貌似有错,改用其它的exe 或自己重新编译一个c++程序 就可以执行啦

请问一下

extendedDesktop 加上这一句之后,打包生成air文件报错
改成desktop extendedDesktop
调不到要用的进程

报错了

extendedDesktop 加上这一句之后 在打包成exe文件的时候报错~~

請改用

desktop extendedDesktop
只有 extendedDesktop 时,似乎会报错

要确保使用的是AIR2.0

要确保使用的是AIR2.0的SDK,并且应用的配置XML中,运行时的设置,也应该是2.0

請問

我在 FLEX 中的 debug mode 能正常使用 native Process 类的功能

但打包的 EXE 每次執行到外部 file 都會一直跳出 cmd 窗口

是否我的設定有誤?

设定没有错误,现阶

设定没有错误,现阶段AIR2 Beta就是这样的,不知道正式版会不会解决这个问题

关于Socket的教程稍后

关于Socket的教程稍后送出

期待SSL/TLS

期待SSL/TLS Socket的教程

发表新评论

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

更多格式化选项信息

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