使用Titanium Mobile编译应用程序后,JavaScript代码会发生什么?

30

我从appcelerator安装了Titanium并构建了“KitchenSink”示例应用程序。

一切正常,我只是想知道在构建的应用程序中javascript代码在哪里。

我在Xcode项目和结果应用程序中进行了grep搜索,因为我在Library/Application Support/iPhone Simulator/....KitchenSink.app中找到了它,但我找不到任何来自.js文件的函数名称,甚至没有在应用程序中使用的字符串文本。

我找到的最接近的信息是这里的答案:How Does Appcelerator Titanium Mobile Work?但我不太清楚这个过程是如何工作的。

javascript代码被编译成二进制代码(使用什么编译器?),还是仅被转换为某些特殊的数据格式,并在运行的应用程序中解释?

更新:

这是我在KitchenSink/build/android目录中看到的内容:

michal:bin mac$ find . -name table_view_layout\*
./assets/Resources/examples/table_view_layout.js
./assets/Resources/examples/table_view_layout_2.js
./assets/Resources/examples/table_view_layout_3.js
./assets/Resources/examples/table_view_layout_4.js
./assets/Resources/examples/table_view_layout_5.js
./classes/org/appcelerator/generated/examples/table_view_layout.class
./classes/org/appcelerator/generated/examples/table_view_layout_2.class
./classes/org/appcelerator/generated/examples/table_view_layout_3.class
./classes/org/appcelerator/generated/examples/table_view_layout_4.class
./classes/org/appcelerator/generated/examples/table_view_layout_5.class
michal:bin mac$ unzip -t app.apk | grep table_view_layout
    testing: assets/Resources/examples/table_view_layout.js   OK
    testing: assets/Resources/examples/table_view_layout_2.js   OK
    testing: assets/Resources/examples/table_view_layout_3.js   OK
    testing: assets/Resources/examples/table_view_layout_4.js   OK
    testing: assets/Resources/examples/table_view_layout_5.js   OK

之前我没有查看过app.apk,我只能看到与每个JavaScript文件对应的这些类文件。因此,我认为在Android上JavaScript被编译为JVM。为什么这些类文件在app.apk中找不到?


1
我可能说错了,但是几个月前我尝试使用Appcelerator开发Android应用时,我有一种印象,即JavaScript代码根本没有被编译。相反,它与.apk文件一起发送,并且在运行时由JavaScript解释器运行JavaScript代码。否则,为什么他们要首先将JavaScript代码包含在apk文件中呢? - Fredrik Wallenius
2个回答

47

Titanium并不是像之前所说的那样包装了一个Web视图(虽然这准确解释了Phonegap如何工作)。Jeff在问题中的回答是对Titanium运作方式的技术上正确的解释,但以下是我听过的迄今为止最好的版本,来自Marshall Culpepper

确实,在早期的1.0版本之前,Titanium移动版使用了WebView(在Android和iOS上都是如此)。然而,这现在已经不再是真的,因为自2010年3月我们发布了1.0版本以来就不是这样了。

自 1.0 版本以来,我们已经与应用程序一起提供了两个单独的JavaScript运行时,并且我们直接运行JavaScript代码没有WebView。您的整个应用程序从头到尾都由JS控制,我们提供了全面的原生API集,使这一切成为可能。从UI小部件(是的,包括WebView),核心API,如Networking、Filesystem、Database,甚至到特定于操作系统的事物,如Android中的JS Activities。在JS运行时方面,我们在iOS中正在提供WebKit的JavaScriptCore的分支版本,以及在Android中使用Rhino 1.7 R3 CVS的快照。我们对JavaScript源代码的实际处理取决于平台,但通常会分解成以下几个部分:

  • 静态分析源代码以查找对Titanium模块的引用
  • 本地化字符串(strings.xml)、应用程序元数据(tiapp.xml)和密度特定的图像都生成了平台特定的类似物。
  • 在iOS中:
    • 生成XCode项目/配置
    • JS源代码Base64编码,并作为一个变量内联到生成的C文件中
    • 使用xcodebuild生成最终的二进制文件
    • 应用程序id分配、签名密钥等应用
    • iTunes和其他一些粘合剂被用来将IPA发送到您的iOS设备
  • 在Android中:
    • 生成Android/Eclipse项目
    • 在“开发”模式下,JS源代码被打包为APK资源
    • 在“发布”(生产)模式下,当您准备好发布应用程序时,我们使用Rhino JSC编译器将JS编译为Java字节码。您还可以通过在tiapp.xml中设置“ti.android.compilejs”为“true”来启用开发模式下的此功能,详情请参见:http://developer.appcelerator.com/question/100201/enable-android-byte-code-compile
    • dex、aapt和其他Android SDK工具用于构建和生成最终APK
    • adb和keytool用于将APK推送到模拟器和/或设备上
  • 虽然我可以深入介绍每个这些点的特定细节,但我想要强调的是,我们不再使用WebView作为我们的Javascript引擎。然而,您仍然可以嵌入WebViews,我们提供了一些简单的集成方式,以便您从嵌入的WebView中调用Titanium API。


一个"Appcelerator桌面应用程序"的源代码"HTML CSS & JS"是否可以在"Windows操作系统"中查看? - cupcake
1
如果问题是“在Windows(或任何操作系统)上是否可以查看Titanium桌面应用程序的HTML/CSS/JS”,目前的答案是肯定的。我们目前不提供任何自动加密或将源代码包含在二进制文件中的功能,但将来可能会提供。与此同时,我们建议用户将他们的JavaScript源代码进行合并、压缩和混淆处理。 - Kevin Whinnery

4
在你提供的问题中,jhaynie的意思是Titanium会解释你的JS代码并将其转换成几乎与Objective-C相同的东西。
在Web应用程序中,浏览器读取和解释您的JavaScript,并运行相关的本地代码(可能是C ++)。例如,浏览器可能会说:“这个脚本正在执行getElementById(),所以我会运行自己的C ++方法来完成它。” Titanium正在找出预先编译JS-> C ++(或在这种情况下,JS-> Objective-C)的内容。必要时仍然保留解释器以处理您的动态代码,但它会尽可能地进行转换和编译。
这意味着您不会找到任何看起来与您最初编写的脚本类似的东西。必须留给解释器的任何内容仍然会被处理和转换,而您的符号也会更改(例如,对myTestFunction()的调用可能会转换为A(),或10001101001101:P)。
通常使用JavaScript的方式是由正在运行的程序实时解释它。这里不是这样,这就是为什么您看不到脚本痕迹的原因。
- JavaScript被预处理
Titanium像其他程序一样解释您的脚本(例如Web浏览器)。它确定了您的脚本对Titanium API的依赖关系并设置了这些内容。然后,它将您的符号直接映射到(在iPhone的情况下)Objective-C。
程序通常会读取您的脚本(这只是一个字符串),对其进行解释,并运行C代码以完成您的脚本要求的工作。 Titanium在此之前执行此操作以确定应该运行什么C代码,并提前进行转换。
- 在可能的情况下编译代码
基于您的代码及其对Titanium API的依赖关系的解释,Titanium确定可以直接编译哪些代码,以及必须不编译哪些代码以允许JavaScript的完全动态性。我不知道它是如何选择编译什么和不编译什么的,但如果您想了解那么多细节,可以查看源代码。
必须仍然解释(保留为脚本)的代码仍将转换为导致更有效地映射到本机代码的符号。因此,它仍然是解释脚本,但这并不意味着它仍然是JavaScript。这意味着脚本的这些部分仍将比通常的JavaScript运行得更快。
对于iPhone,可编译的C使用GCC编译为本机二进制文件。
- 您有一个可运行的应用程序*
现在您有一个可以在移动设备上运行的应用程序。您的可编译代码已经编译并以闪电般的速度运行,而其余部分则以更高效的方式进行转换和解释,可以接近闪电般的速度:P
我希望现在这些内容对你有所帮助,因为这是我能提供的全部信息! :D

1
这仍然非常令人困惑。编译是将用编程语言编写的源代码转换为目标代码 - 可执行代码的过程。一个部分如何被编译而另一个部分不被编译?编译是通过什么手段进行的,它是否生成Objective-C并使用gcc进行编译?JavaScript是否被转换为某种结构,然后在运行程序中进行解释? - Michal
我将尝试在上面的答案中添加另一个简化版本。其中很多内容将是冗余的... - Brendan
Brendan,感谢您提供有用的解释。对于具有Web开发背景的人来说,您的答案可能已经足够好了,但对于我这样从编程的另一侧面来看的人来说,还不够。我不知道是否有任何JavaScript编译器,因此我怀疑是否真的进行了编译。我检查了Titanium为Android生成的内容,我在那里看到了每个js脚本的生成的jvm class文件。嗯,Java总是被解释的,所以在该平台上这是一种自然的方式。我认为他们使用jsc来编译它。但是对于iPhone,这是如何工作的-我没有看到任何生成的内容。 - Michal
Peter Knego:我编辑了问题,并解释了我是如何想出编译JavaScript的想法的。无论如何,你可能是对的,它在最终产品中没有被使用——那么为什么会在构建过程中生成它呢? - Michal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接