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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4217551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 10:43:20  来源:igfitidea点击:

What happens to JavaScript code after app is compiled using Titanium Mobile

javascriptiphoneandroidobjective-ctitanium

提问by Michal

I installed Titanium from appcelerator and built the "KitchenSink" example application.

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

All works well, I'm just wondering where does the javascript code ends up in a built app.

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

I grep-ed the Xcode project and also the result application as I found it in Library/Application Support/iPhone Simulator/....KitchenSink.app, but I can't find any function names from .jsfiles, not even string texts used within the application.

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

Nearest information I found is an answer here : How Does Appcelerator Titanium Mobile Work?but I do not understand clearly how the process works.

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

Is the javascript code being compiled into a binary code (what compiler is used then?), or is it just transformed in some special data-format and interpreted in a running application ?

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

Update:

更新:

This is what I can see in a build/android directory of KitchenSink:

这是我在 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

I didn't look into app.apk before, all I could see were these class files corresponding to each of the javascript files. Therefore I assumed that on Android javascript is being compiled for JVM. Why can't these be found in app.apk ?

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

回答by Kevin Whinnery

Titanium is not a wrapper around a web view as stated before (though that accurately explains how Phonegap works). Jeff's answer, linked in the question, is a technically correct explanation of how Titanium works, but here's the best version I've heard so far, from Marshall Culpepper:

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

It's true that Titanium Mobile used the WebView (in both Android and iOS) in the pre-1.0 days. However, this is no longer true and hasn't been since our 1.0 release is March 2010.

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

Since 1.0, we've shipped two separate Javascript runtimes with our apps, and we are running the Javascript code directly withouta WebView. Your entire app from start to finish is now controlled by JS, and we provide a comprehensive set of Native APIs that enable this. Everything from UI widgets (yes, including WebView), Core APIs like Networking, Filesystem, Database, all the way to OS-specific things like JS Activities in Android. On the JS runtime front, we're shipping a forked version of WebKit's JavaScriptCore in iOS and a snapshot of Rhino 1.7 R3 CVS for Android. What we actually do with your javascript source is dependent on the platform, but generally it breaks up like this:

从 1.0 开始,我们的应用程序附带了两个单独的 Javascript 运行时,并且我们直接运行 Javascript 代码而没有WebView。您的整个应用程序从头到尾都由 JS 控制,我们提供了一套全面的原生 API 来实现这一点。从 UI 小部件(是的,包括 WebView)、核心 API(如网络、文件系统、数据库),一直到操作系统特定的事物(如 Android 中的 JS 活动),应有尽有。在 JS 运行时方面,我们将在 iOS 中发布 WebKit 的 JavaScriptCore 的分叉版本,以及用于 Android 的 Rhino 1.7 R3 CVS 快照。我们实际使用您的 javascript 源代码做什么取决于平台,但通常它会像这样分解:

  • Source is statically analyzed to find references to Titanium modules
  • Localization strings (strings.xml), App metadata (tiapp.xml), and density specific images all generate platform specific analogs.
  • In iOS:
    • An XCode project / configuration is generated
    • JS Source is base64'd and inlined as a variable into a generated C file
    • xcodebuild is used to generate the final binaries
    • provisioning profiles, signing keys etc are applied
    • iTunes and some other glue are used to send the IPA to your iOS device
  • In Android:
    • An Android / Eclipse project is generated
    • In "Development" mode, JS source is packaged as APK assets
    • In "Distribution" (production) mode, when you're ready to ship the app, we compile the JS to Java bytecode using the Rhino JSC compiler. You can also enable this during development mode by setting "ti.android.compilejs" to "true" in tiapp.xml, see: http://developer.appcelerator.com/question/100201/enable-android-byte-code-compile
    • dex, aapt, and other Android SDK tools are used to build and generate the final APK
    • adb and keytool are used for pushing the APK out to the emulator and/or device
  • 静态分析源以查找对 Titanium 模块的引用
  • 本地化字符串 (strings.xml)、应用程序元数据 (tiapp.xml) 和特定于密度的图像都生成特定于平台的类似物。
  • 在iOS中:
    • 生成了一个 XCode 项目/配置
    • JS 源是 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 canhowever still embed WebViews, and we provide some simple integration that allows you to call Titanium APIs from an embedded WebView.

关于这些点中的每一个,我可以深入研究更多细节,但我想说的是我们不再使用 WebView 作为我们的 Javascript 引擎。然而,您仍然可以嵌入 WebView,我们提供了一些简单的集成,允许您从嵌入式 WebView 调用 Titanium API。

回答by Brendan

What jhaynie is saying in your linked question is that Titanium interprets your JS code and converts it into something that is almost identical to Objective-C.

jhaynie 在您链接的问题中所说的是 Titanium 解释您的 JS 代码并将其转换为与 Objective-C 几乎相同的内容。

In a web application, the browser reads and interprets your Javascript and runs associated native code (perhaps C++) internally. For instance, the browser might say, "This script is executing getElementById(), so I'll run my own C++ methods to accomplish that." What Titanium is doing is figuring out what that JS->C++ (or in this case, JS->Objective-C) would be in advance, and compiling that. It still leaves an interpreter open where necessary for your dynamic code, but it will convert and compile what it can.

在 Web 应用程序中,浏览器读取和解释您的 Javascript 并在内部运行相关的本机代码(可能是 C++)。例如,浏览器可能会说,“这个脚本正在执行getElementById(),所以我将运行我自己的 C++ 方法来完成它。” Titanium 正在做的是提前弄清楚 JS->C++(或者在这种情况下,JS->Objective-C)是什么,然后编译它。它仍然在您的动态代码需要的地方打开一个解释器,但它会转换和编译它所能做的。

That means you won't find anything that looks similar to what you originally wrote in your script. Anything that must be left to an interpreter is still processed and converted, and your symbols will change (e.g. a call to myTestFunction()might be converted to A(), or 10001101001101:P).

这意味着您将找不到与您最初在脚本中编写的内容相似的任何内容。任何必须留给解释器的东西仍然会被处理和转换,你的符号也会改变(例如,对 的调用myTestFunction()可能会被转换为A(), 或10001101001101:P)。



The usualuse of Javascript is to have it interpreted real-time by a running program. That's not what's going on here, and that's why you can't see any trace of your script.

Javascript的通常用途是让它由正在运行的程序实时解释。这不是这里发生的事情,这就是为什么您看不到任何脚本痕迹的原因。

  • Javascript is pre-processed

    Titanium performs the interpretation of your script as any other program would do (such as a web browser). It figures out what dependencies your script has on the Titanium API and sets that stuff up. It then maps your symbols directly into (in the case of the iPhone) Objective-C.

    A program usually would read in your script (which is a simply a String), interprets it, and runs C code to accomplish what your script asked for. Titanium does this before-hand to figure out what C code should be run, and does the conversion in advance.

  • Javascript 是预处理的

    Titanium 像任何其他程序(例如 Web 浏览器)一样执行脚本的解释。它计算出您的脚本对 Titanium API 的依赖关系并进行设置。然后它将您的符号直接映射到(在 iPhone 的情况下)Objective-C。

    一个程序通常会读入你的脚本(它只是一个字符串),解释它,然后运行 ​​C 代码来完成你的脚本所要求的。Titanium 事先这样做是为了确定应该运行什么 C 代码,并提前进行转换。

  • Code is compiled where possible

    Based on the interpretation of your code and its dependencies on the Titanium API, Titanium figures out what code can be directly compiled, and what must not be compiled in order to allow for they full dynamics of Javascript. I don't know how it chooses what does and doesn't get compiled, but you could check out the source if you want to know that much detail.

    Code that must still be interpretted (left as a script) is still converted into symbols that result in more efficient mapping to native code. So it's still an interpreted script, but that doesn't mean it's still Javascript. This means that these parts of your script will still run faster than usual Javascript.

    For iPhone, the compilable C is compiled with GCC to create a native binary.

  • 在可能的情况下编译代码

    基于对代码的解释及其对 Titanium API 的依赖,Titanium 确定哪些代码可以直接编译,哪些代码不能编译,以允许它们完全动态的 Javascript。我不知道它如何选择编译和不编译的内容,但是如果您想了解那么多细节,可以查看源代码。

    仍然必须解释的代码(作为脚本保留)仍然被转换为符号,从而更有效地映射到本机代码。所以它仍然是一个解释脚本,但这并不意味着它仍然是 Javascript。这意味着脚本的这些部分仍然会比通常的 Javascript 运行得更快。

    对于 iPhone,

  • You have a runnable app*

    Now you have an app that you can run on your mobile device. Your compilable code has been compiled and runs at lightning speed, while the rest is converted and still interpreted in a more efficient way which runs at near lightning speed. :P
  • 您拥有了一个可运行的应用程序*

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



  • I hope this makes sense now, because it's all I've got! :D

    我希望这现在有意义,因为这就是我所拥有的!:D