使用 Titanium Mobile 编译应用程序后 JavaScript 代码会发生啥

Posted

技术标签:

【中文标题】使用 Titanium Mobile 编译应用程序后 JavaScript 代码会发生啥【英文标题】:What happens to JavaScript code after app is compiled using Titanium Mobile使用 Titanium Mobile 编译应用程序后 JavaScript 代码会发生什么 【发布时间】:2011-05-12 04:18:38 【问题描述】:

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

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

我对 Xcode 项目和结果应用程序进行了 grep-ed,因为我在 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 上正在为 JVM 编译 javascript。为什么在 app.apk 中找不到这些?

【问题讨论】:

我在这里可能是错的,但是当我几个月前尝试适用于 Android 的 Appcelerator 时,我得到的印象是 javascript 代码根本没有编译。相反,它是随 .apk 文件和一个在运行时运行 javascript 代码的 javascript 解释器一起提供的。否则他们为什么会首先将 javascript 代码包含在 apk 文件中? 【参考方案1】:

Titanium 并不是如前所述的 Web 视图的包装器(尽管这准确地解释了 Phonegap 的工作原理)。 Jeff 在问题中的回答是对 Titanium 工作原理的技术正确解释,但这是我迄今为止听到的最好的版本,来自Marshall Culpepper:

确实,Titanium Mobile 在 1.0 之前的日子里使用了 WebView(在 Android 和 ios 中)。但是,这不再是事实,而且自 2010 年 3 月我们的 1.0 版本以来一直如此。

自 1.0 以来,我们已经为我们的应用提供了两个独立的 Javascript 运行时,并且我们直接运行 Javascript 代码没有 WebView。您的整个应用程序从头到尾现在都由 JS 控制,我们提供了一套全面的 Native API 来实现这一点。从 UI 小部件(是的,包括 WebView)、网络、文件系统、数据库等核心 API,一直到特定于操作系统的东西,如 Android 中的 JS 活动,应有尽有。在 JS 运行时方面,我们在 iOS 中发布了 WebKit 的 JavaScriptCore 的分叉版本和用于 Android 的 Rhino 1.7 R3 CVS 的快照。我们对您的 javascript 源的实际处理取决于平台,但通常它会像这样分解:

对源进行静态分析以查找对 Titanium 模块的引用 本地化字符串 (strings.xml)、应用元数据 (tiapp.xml) 和特定于密度的图像都会生成特定于平台的类似物。 在 iOS 中: 生成一个 XCode 项目/配置 JS 源代码经过 base64 处理并作为变量内联到生成的 C 文件中 xcodebuild 用于生成最终的二进制文件 应用配置文件、签名密钥等 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 引擎。您可以仍然嵌入 WebView,我们提供了一些简单的集成,允许您从嵌入式 WebView 调用 Titanium API。

【讨论】:

“Appcelerator Desktop App”的源代码“html CSS & JS”是否可以在“Windows OS”中看到?? 如果问题是“能否在 Windows(或任何操作系统)上查看 Titanium 桌面应用程序的 HTML/CSS/JS”,目前的答案是肯定的。我们不提供任何自动加密或在二进制文件中包含源代码,但我们将来可能会这样做。与此同时,我们建议人们组合、缩小和混淆他们的 JavaScript 源代码。【参考方案2】:

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

【讨论】:

这仍然很混乱。编译是将用编程语言编写的源代码转换为目标代码(可执行代码)的过程。如何编译一部分而另一部分不编译。编译是通过什么方式完成的,它会生成 Objective-c 并使用 gcc 进行编译吗? javascript 是否被转换成某种结构,然后在运行的程序中被解释? 我将尝试在上面的答案中添加另一个简化版本。其中大部分都是多余的...... 布伦丹,感谢您提供有用的解释。对于具有 Web 开发背景的人来说,您的答案可能已经足够好了,但对于来自编程另一面的我来说,这并没有削减它。我不知道有任何 javascript 编译器,所以我怀疑是否真的编译过任何东西。我检查了 Titanium 为 Android 生成的内容,我看到每个 js 脚本都有一个生成的 jvm class 文件。好吧,java 总是被解释,所以在那个平台上这是一种自然的方式。我认为他们使用jsc 来编译它。但这对 iPhone 有什么作用——我没有看到那里生成任何东西。 Peter Knego:我编辑了这个问题,解释了我是如何产生编译 javascript 的想法的。无论如何,你可能是对的,它没有在最终产品中使用 - 那么为什么它会在构建中产生呢?

以上是关于使用 Titanium Mobile 编译应用程序后 JavaScript 代码会发生啥的主要内容,如果未能解决你的问题,请参考以下文章

Titanium Mobile JSON 和 Android 中的特殊字符

Titanium Mobile 在 iOS 上无法获得正确的准确性

sh Adb安装已在Titanium中编译Android应用程序 - 来自http://skypanther.com/2015/10/arggh-failed-android-install

使用 Titanium 的多点连接

Titanium:不能将相机与 OptionDialog 一起使用

Titanium - 确定应用程序崩溃的原因