30

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

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

我对 Xcode 项目和我在 中找到的结果应用程序进行了 grep-ed Library/Application Support/iPhone Simulator/....KitchenSink.app,但我无法从.js文件中找到任何函数名称,甚至找不到应用程序中使用的字符串文本。

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

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 中找不到这些?

4

2 回答 2

47

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

确实,Titanium Mobile 在 1.0 之前的日子里使用了 WebView(在 Android 和 iOS 中)。然而,这不再是真的,而且自从我们的 1.0 版本是 2010 年 3 月以来就没有了。

从 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 Source 是 base64'd 并作为变量内联到生成的 C 文件中
    • xcodebuild 用于生成最终的二进制文件
    • 应用配置文件、签名密钥等
    • iTunes 和其他一些胶水用于将 IPA 发送到您的 iOS 设备
  • 在安卓中:
    • 生成一个 Android / Eclipse 项目
    • 在“开发”模式下,JS 源被打包为 APK 资源
    • 在“分发”(生产)模式下,当您准备好发布应用程序时,我们使用 Rhino JSC 编译器将 JS 编译为 Java 字节码。您也可以在开发模式下通过在 tiapp.xml 中将“ti.android.compilejs”设置为“true”来启用此功能,请参阅:http: //developer.appcelerator.com/question/100201/enable-android-byte-code-编译
    • dex、aapt 等 Android SDK 工具用于构建和生成最终的 APK
    • adb 和 keytool 用于将 APK 推送到模拟器和/或设备

There are many more details that I could dive into specifically on each of these points, but the point I wanted to drive home is that we no longer use the WebView as our Javascript engine. You can however still embed WebViews, and we provide some simple integration that allows you to call Titanium APIs from an embedded WebView.

于 2011-01-25T20:36:58.700 回答
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,

  • 您有一个可运行的应用程序*

    现在您有一个可以在移动设备上运行的应用程序。您的可编译代码已经编译并以闪电般的速度运行,而其余代码则被转换并仍然以更有效的方式解释,以接近闪电的速度运行。:P

  • 我希望现在这是有道理的,因为这就是我所拥有的!:D

    于 2010-11-18T17:18:24.710 回答