游戏开发者社区

[AIR] AIR 2放大镜应用或者AIR如何与Java程序通讯

查看: 6201|回复: 10

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

威望
138 点
义气
98 点

AQ小生 AQ大侠 大光棍节纪念勋章 蓝色海洋水心勋章 赤子之心勋章 译林军两仪译士

发表于 2009-12-9 09:14:14 |显示全部楼层
Adobe AIR 2 我最喜欢的功能是 Native Processes: 发起和控制本地程序,与本地程序通讯的能力。这个在 AIR 应用安装的号及其上随处都可执行。个人认为这个功能打开了一个新AIR应用的范围。当你将此这个更能添加给socket服务时,你将会得到一个强有力的用来为桌面创建 RIA 应用的平台。
当我听到这个功能将在AIR2中实现的时候,我兴奋得跳了起来。为何?好的,让我们回到2008年我们发起AIR1.0,我的朋友Serge Jespers 为AIR Tour创建了一个最酷的AIR。它是这个世界上最小的视频播放器。基本上,它让你从Dock的应用图标中观看视频。
这个应用非常的酷,但是有一个小问题:它太他妈(原译)小了以至于看不到发生了什么事情。作为一个工程师,我花了不少时间来尝试一些工程解决方案。当然,我也有要求 Serge 重写这个应用以把它变大,但是这个不是一个工程解决方案。如果这样的话,财务人员或者经理就会来找你喝咖啡了。我的解决方案是建立另一个 AIR 应用,这个应用的作用是用来放大图标里面播放的视频。这个应用将产生一个数字放大镜的效果。
使用 AIR 2 我可以非常简单的实现这个数字放大镜的应用。以下你将看到我的应用的截屏。它有两个窗口。第一个窗口时放大镜的视窗端口。你可以看见它每秒处理多少帧,你可以控制放大倍数,你可以拖动它们屏幕跑。第二个窗口显示了放大的图片。


内部
我要如何做这个呢? 这个应用有两个主要部分。一个是AIR应用本身。它渲染UI,控制视窗端口和方法因素,调整图片比例。 第二部分是一个Java部分,它用于捕获部分截屏的。此Java程序时由 AIR 应用控制的。
使用AIR2里面的 NativeProcess 和 NativeProcessStartupInfo 类, 你可以发起一个可执行程序。你可以使用标准输出和输入设备来和此刻执行程序通讯。我把Java程序写成输入截图的字节到标准输出设备。它坚挺标准输入指令,例如截图,设置视窗端口,或者结束本程序。我将Java程序编译成一个可执行的JAR文件,然后把它放置到 AIR 应用的根目录下。
为了捕获到Java程序的输出,所有你需要做的是在NativeProcess 实例上为标准输出事件注册一个监听器。当你想发送一个命令的时候,你写一些字节到同一个对象的standardInput 属性。以下是一小段代码,想看完整代码的话请查看AIR应用里面的ScreenShotService 类。
  1. 1: private var nativeProcess:NativeProcess;
  2.    2: private var npInfo:NativeProcessStartupInfo;
  3.    3: //setting the arguments for starting the Java program
  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: //setting the path to the native process
  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:  * Read the data from the standard ouput.
  22.   22:  * Before reading a png, first you have to read the length of the image
  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: //sending take command to the Java process
  31.   31: nativeProcess.standardInput.writeMultiByte("take\n", "utf-8");
复制代码
这是相关的Java代码(你可以在应用的源文件ScreenShot.java 里面找到完整代码):
  1. 1: /**
  2.    2:  * @param width of the screen capture
  3.    3:  * @param height of the screen capture
  4.    4:  * @param args
  5.    5:  */
  6.    6: public static void main(String[] args) {
  7.    7:      if (args.length == 2) {
  8.    8:          width = Integer.parseInt(args[0]);
  9.    9:          height = Integer.parseInt(args[1]);
  10.   10:      }
  11.   11:
  12.   12:     ScreenShot s = new ScreenShot();
  13.   13:     BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  14.   14:     String text = "";
  15.   15:     String[] tokens;
  16.   16:
  17.   17:     while (true) {
  18.   18:         try {
  19.   19:             text = in.readLine();
  20.   20:             if (text.equals("take")) {
  21.   21:                 s.capturePortion(x, y, width, height);
  22.   22:             } else if (text.equals("terminate")) {
  23.   23:                 return;
  24.   24:             } else if (text.length() > 0) {
  25.   25:                 tokens = text.split("\\|");
  26.   26:                 if (tokens.length < 4)
  27.   27:                     continue;
  28.   28:                 x = Integer.parseInt(tokens[0]);
  29.   29:                 y = Integer.parseInt(tokens[1]);
  30.   30:                 width = Integer.parseInt(tokens[2]);
  31.   31:                 height = Integer.parseInt(tokens[3]);
  32.   32:             }
  33.   33:         } catch (IOException e) {
  34.   34:             System.err.println("Exception while reading the input. " + e);
  35.   35:         }
  36.   36:     }
  37.   37: }
  38.   38:
  39.   39: /**
  40.   40:  * Capture a portion of the screen
  41.   41:  */
  42.   42: public void capturePortion(int x, int y, int w, int h) {
  43.   43:     try {
  44.   44:         if (robot == null)
  45.   45:             robot = new Robot();
  46.   46:         BufferedImage img = robot.createScreenCapture(new Rectangle(x, y, w, h));
  47.   47:         ByteArrayOutputStream output = new ByteArrayOutputStream();
  48.   48:         ImageIO.write(img, imageType, output);
  49.   49:
  50.   50:         DataOutputStream dataOutputStream = new DataOutputStream(System.out);
  51.   51:         //output the buffer size
  52.   52:         dataOutputStream.writeInt(output.size());
  53.   53:         //output the buffer
  54.   54:         dataOutputStream.write(output.toByteArray());
  55.   55:         dataOutputStream.flush();
  56.   56:
  57.   57:         output.close();
  58.   58:     } catch (AWTException e) {
  59.   59:         System.err.println("Exception while capturing screen. " + e);
  60.   60:     } catch (IOException e) {
  61.   61:         System.err.println("Exception while writting the image bytes. " + e);
  62.   62:     }
  63.   63: }
复制代码
我不是一个设计人员。我还是想通过使用Adobe Illustrator和Flash Catalyst管理取得一个比较大方的视觉效果。我在Illustrator里面创建了设计,然后使用Flash Catalyst我将图形转换成一个Flex应用。最后使用Flash Builder4我增加了逻辑部分。

源代码和本地安装装置
你可以从此处下载 here Flex项目, 从此处 here下载Mac安装装置, 从此处here 可以下载Windows可执行程序。此程序要求 Java 5 或者更新的版本和Adobe AIR 2 运行环境。
在AIR里面使用 Native Processes 需要知道的事情
为了激活此功能你需要将extendedDesktop 功能添加到应用的描述文件。将此标签添加为应用标签的子标签:
  1.    1: <supportedProfiles>extendedDesktop</supportedProfiles>
复制代码
当使用此功能的时候,你不可以将你的应用包装成一个AIR文件以用来分发。你必须使用本地安装装置。做这个的最简单的方法是从Flash Builder里面到处发行(你取的AIR文件,这个是你用来分发你的应用的)。然后你在命令行里面使用 adt 以创建本地安装装置。如果你想得到一个Mac安装装置,那么你就在Mac上面做这步,如果你想得到一个Windows的,那么你就在Windows里面做。命令行看起来将是如下:
  1.   1: adt -package -target native myApp.exe myApp.air
复制代码
更多关于如何创建AIR的本地安装装置请参考此处here (确保你使用的是AIR 2里面的adt 而不是老版本里面的)。
如果你在使用生成的本地安装装置安装应用时看见如下图这样的一个错误,那么你必须在你的根文件夹下面创建一个名airappinstall.log 的文件。这个日志文件将会告诉你错在哪里。在我的案例当中,错误信息时“failed while validating native package: Error: Missing digested package file: .DS_Store starting cleanup of temporary files” (我通过删除源文件夹里面的 DS_Store 文件修补此问题)。


最后, 你可以在运行时检查应用使以下这个扩展了桌面能力:
  1. 1: if (NativeProcess.isSupported)
  2.    2:     //extended desktop profile is available
  3.    3: else
  4.    4:     //extended desktop profile is not available
复制代码
下一步是什么?
如果你未准备好,下载 Adobe AIR2 运行环境和SDK,玩一玩这些新功能。你可以在Christian Cantrell的 blog找到一些非常好的关于AIR 2的新功能的文章。
我已经有了另一个想法:一个AIR应用需要如何做到屏幕分享呢?敬请关注,我想我很快就可以把这个弄出来!
PS. 非常感谢来自Romanian AIR团队的我的朋友Chicu 和 Raul的帮助。
本帖评分记录:1人评分    银子+20 
值班管理员 银子 + 20

举报

Rank: 5Rank: 5

威望
3 点
义气
5 点

AQ大侠 AQ小生

发表于 2009-12-9 09:37:28
COOL!!! 期待他的屏幕分享计划

举报

Rank: 5Rank: 5

威望
1 点
义气
5 点

AQ小生

发表于 2009-12-9 09:43:59
很不错,而且我是沙发

举报

Rank: 5Rank: 5

威望
1 点
义气
5 点

AQ小生

发表于 2009-12-9 09:44:36
刷新了一下,发现我是地板

举报

Rank: 1

威望
0 点
义气
7 点
发表于 2009-12-9 15:40:33
我只能在地下室了

举报

Rank: 3Rank: 3Rank: 3

威望
8 点
义气
5 点
发表于 2009-12-15 13:32:28
非常棒,竟然没有人来叫好,奇怪了

举报

Rank: 4

威望
2 点
义气
5 点
发表于 2010-6-22 15:28:38
为什么这个FLex工程不能下载呢?

举报

Rank: 4

威望
2 点
义气
5 点
发表于 2011-6-9 16:39:32
真nb ,佩服 ,正想这个东西呢

举报

Rank: 4

威望
4 点
义气
5 点
发表于 2011-11-7 09:34:14
很好很强大

举报

Rank: 9Rank: 9Rank: 9

威望
10 点
义气
16 点

AQ大侠 AQ小生

发表于 2012-1-20 23:50:39
这么好的功能, 要顶一个。

举报

Rank: 3Rank: 3Rank: 3

威望
0 点
义气
5 点
发表于 2012-2-15 22:52:10

举报

您需要登录后才可以回帖 登录 | 注册

关闭

江湖传闻

手机版|9RIA.com ( 京ICP备11007422号-2 

GMT+8, 2017-2-26 00:20 , Processed in 0.091189 second(s), 20 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部