AIR2.0入门教程[五]:与Java应用交互

在之前的一篇文章中,我介绍了如何使用AIR2.0新增的NativeProcess类与本地进程进行交互和通讯,在那个例子里面我们使用了C++的代码,实际上只要是基于命令行的标准输入输出,AIR2.0的应用是可以和任何语言编写的本地进程进行交互的。在今天的例子中,我们将学习如何和Java编写的本地进程(.jar文件)进行交互。

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

注:这篇文章所涉及的源码和示例来自于Mihai的一篇文章

回顾

在AIR2.0中,我们可以使用NativeProcessNativeProcessInfo这两个类,来启动一个可执行文件。当进程启动后,你就可以使用标准输入和标准输入来与进程通讯。

结合Java

首先,你可以下载示例项目,这个项目包含了两个部分:

  1. AIR部分:是一个基于Flex4 Framework的AIR项目,实现了用户界面(UI)部分的工作,界面包含两个窗口,如下图所示,右边的窗口是主窗口,你可以看到当前的帧频,然后你还可以控制左侧的滚动条来放大和缩小右侧的图像。左边的窗口则用来显示遮盖区域的图像。
  2. Java部分:控制定位到屏幕的特定区域,然后捕获截图,这个部分被AIR部分所控制。

示例截图:

你可以使用Flash Builder4,将下载的示例项目导入,编译运行看一下结果,注意这个项目使用了Flex4的Framework,而且有可能需要你修改SDK的配置,参见第一篇AIR2.0教程

在AIR部分的代码中,我们需要创建一个NativeProcess的实例来注册侦听标准输出事件。首先我们需要调用Java命令,启动我们的.jar文件,然后输入“take”命令来获取屏幕截图

  1. 1: private var nativeProcess:NativeProcess;
  2. 2: private var npInfo:NativeProcessStartupInfo;
  3. 3: //启动进程,并输入参数
  4. 4: var arg:Vector.<String> = new Vector.<String>;
  5. 5: arg.push("-jar");
  6. 6: arg.push(File.applicationDirectory.resolvePath("screenshot.jar").nativePath);
  7. 7: arg.push("130");
  8. 8: arg.push("100");
  9. 9:
  10. 10: npInfo = new NativeProcessStartupInfo();
  11. 11: //设置Java的路径
  12. 12: npInfo.executable = new File("/Library/Java/Home/bin/java");
  13. 13: npInfo.arguments = arg;
  14. 14:
  15. 15: nativeProcess = new NativeProcess();
  16. 16: nativeProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOutputData);
  17. 17: //start the process
  18. 18: nativeProcess.start(npInfo);
  19. 19:
  20. 20: /**
  21.   21: * 从标准输出流中读取数据
  22.   22: * 在读取PNG之前,首先需要读取图片的尺寸
  23.   23: */
  24. 24: private function onStandardOutputData(e:ProgressEvent):void {
  25. 25: //reading the available bytes from the standard output buffer of the process
  26. 26: nativeProcess.standardOutput.readBytes(_processBuffer, _processBuffer.length, nativeProcess.standardOutput.bytesAvailable);
  27. 27: ...
  28. 28: }
  29. 29:
  30. 30: //向Java进程发送take命令
  31. 31: nativeProcess.standardInput.writeMultiByte("take\n", "utf-8");

下面的部分是Java代码,你可以看到,它执行截取屏幕的工作,然后输出字节数组,AIR部分将会把字节数组还原为图片并显示出来:

  1. package org.corlan;
  2.  
  3.  
  4. import java.awt.AWTException;
  5. import java.awt.Rectangle;
  6. import java.awt.Robot;
  7. import java.awt.image.BufferedImage;
  8. import java.io.BufferedReader;
  9. import java.io.ByteArrayOutputStream;
  10. import java.io.DataOutputStream;
  11. import java.io.IOException;
  12. import java.io.InputStreamReader;
  13.  
  14. import javax.imageio.ImageIO;
  15.  
  16. public class ScreenShot {
  17.  
  18. private static int width = 130;
  19. private static int height = 110;
  20. private static int x = 50;
  21. private static int y = 50;
  22.  
  23. private Robot robot;
  24.  
  25. /**
  26.   * 要创建的图片的类型,可以是PNG,GIF或其它
  27.   */
  28. private String imageType = "png";
  29.  
  30. /**
  31. * @param 捕捉屏幕宽度
  32. * @param 捕捉屏幕高度
  33. * @param args
  34. */
  35. public static void main(String[] args) {
  36. if (args.length == 2) {
  37. width = Integer.parseInt(args[0]);
  38. height = Integer.parseInt(args[1]);
  39. }
  40.  
  41. ScreenShot s = new ScreenShot();
  42. BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  43. String text = "";
  44. String[] tokens;
  45.  
  46. while (true) {
  47. try {
  48. text = in.readLine();
  49. if (text.equals("take")) {
  50. s.capturePortion(x, y, width, height);
  51. } else if (text.equals("terminate")) {
  52. return;
  53. } else if (text.length() > 0) {
  54. tokens = text.split("\\|");
  55. if (tokens.length < 4)
  56. continue;
  57. x = Integer.parseInt(tokens[0]);
  58. y = Integer.parseInt(tokens[1]);
  59. width = Integer.parseInt(tokens[2]);
  60. height = Integer.parseInt(tokens[3]);
  61. }
  62. } catch (IOException e) {
  63. System.err.println("Exception while reading the input. " + e);
  64. }
  65. }
  66. }
  67.  
  68. /**
  69.   * 获取屏幕某个区域的截图
  70.   */
  71. public void capturePortion(int x, int y, int w, int h) {
  72. try {
  73. if (robot == null)
  74. robot = new Robot();
  75. BufferedImage img = robot.createScreenCapture(new Rectangle(x, y, w, h));
  76. ByteArrayOutputStream output = new ByteArrayOutputStream();
  77. ImageIO.write(img, imageType, output);
  78.  
  79. DataOutputStream dataOutputStream = new DataOutputStream(System.out);
  80. //输出流的长度
  81. dataOutputStream.writeInt(output.size());
  82. //输出流
  83. dataOutputStream.write(output.toByteArray());
  84. dataOutputStream.flush();
  85.  
  86. output.close();
  87. } catch (AWTException e) {
  88. System.err.println("Exception while capturing screen. " + e);
  89. } catch (IOException e) {
  90. System.err.println("Exception while writting the image bytes. " + e);
  91. }
  92. }
  93.  
  94. }

通过上面的代码,你已经了解了如何将Java进程与AIR应用相结合,接下来就是打包你的AIR应用为本地可执行文件,这样才具备与本地进程通讯的权限,详情请参阅上一篇教程:

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

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

我该怎么关闭它呢~~?

我用java截完图片之后怎么把java进程关闭啊?否则总是会在进程里~

打开程序出现java命令框

每次打开程序的时候总会出现那个命令框怎么解决啊~~

确实是个问题,目前

确实是个问题,目前似乎还没有解决方法

发表新评论

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

更多格式化选项信息

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