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”命令来获取屏幕截图


    private var nativeProcess:NativeProcess;

    private var npInfo:NativeProcessStartupInfo;

    //启动进程,并输入参数

    var arg:Vector.<String> = new Vector.<String>;

    arg.push("-jar");

    arg.push(File.applicationDirectory.resolvePath("screenshot.jar").nativePath);

    arg.push("130");

    arg.push("100");

    npInfo = new NativeProcessStartupInfo();

    //设置Java的路径

    npInfo.executable = new File("/Library/Java/Home/bin/java");

    npInfo.arguments = arg;

    nativeProcess = new NativeProcess();

    nativeProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOutputData);

    //start the process

    nativeProcess.start(npInfo);
   
    /**

    * 从标准输出流中读取数据

    * 在读取PNG之前,首先需要读取图片的尺寸

    */

    private function onStandardOutputData(e:ProgressEvent):void
    {

    //reading the available bytes from the standard output buffer of the process

    nativeProcess.standardOutput.readBytes(_processBuffer, _processBuffer.length,     nativeProcess.standardOutput.bytesAvailable);
    ...

    }

    //向Java进程发送take命令
    nativeProcess.standardInput.writeMultiByte("take/n", "utf-8");

 

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

 


      package org.corlan;

      import java.awt.AWTException;

      import java.awt.Rectangle;

      import java.awt.Robot;

      import java.awt.image.BufferedImage;

      import java.io.BufferedReader;

      import java.io.ByteArrayOutputStream;

      import java.io.DataOutputStream;

      import java.io.IOException;

      import java.io.InputStreamReader;

      import javax.imageio.ImageIO;


      public class ScreenShot {

      

      private static int width = 130;

      private static int height = 110;

      private static int x = 50;

      private static int y = 50;

      

      private Robot robot;

      

      /**

        * 要创建的图片的类型,可以是PNG,GIF或其它

        */

      private String imageType = "png";

      

      /**

      * @param 捕捉屏幕宽度

      * @param 捕捉屏幕高度

      * @param args

      */

      public static void main(String[] args) {

      if (args.length == 2) {

      width = Integer.parseInt(args[0]);

      height = Integer.parseInt(args[1]);

      }

      

      ScreenShot s = new ScreenShot();

      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

      String text = "";

      String[] tokens;

      

      while (true) {

      try {

      text = in.readLine();

      if (text.equals("take")) {

      s.capturePortion(x, y, width, height);

      } else if (text.equals("terminate")) {

      return;

      } else if (text.length() > 0) {

      tokens = text.split("//|");

      if (tokens.length < 4)

      continue;

      x = Integer.parseInt(tokens[0]);

      y = Integer.parseInt(tokens[1]);

      width = Integer.parseInt(tokens[2]);

      height = Integer.parseInt(tokens[3]);

      }

      } catch (IOException e) {

      System.err.println("Exception while reading the input. " + e);

      }

      }

      }

      

      /**

        * 获取屏幕某个区域的截图

        */

      public void capturePortion(int x, int y, int w, int h) {

      try {

      if (robot == null)

      robot = new Robot();

      BufferedImage img = robot.createScreenCapture(new Rectangle(x, y, w, h));

      ByteArrayOutputStream output = new ByteArrayOutputStream();

      ImageIO.write(img, imageType, output);

      

      DataOutputStream dataOutputStream = new DataOutputStream(System.out);

      //输出流的长度

      dataOutputStream.writeInt(output.size());

      //输出流

      dataOutputStream.write(output.toByteArray());

      dataOutputStream.flush();

      

      output.close();

      } catch (AWTException e) {

      System.err.println("Exception while capturing screen. " + e);

      } catch (IOException e) {

      System.err.println("Exception while writting the image bytes. " + e);

      }

      }

      

      }

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值