【问题标题】:Appcelerator Hyperloop vs. Plain Titanium ModulesAppcelerator Hyperloop 与普通钛模块
【发布时间】:2016-12-21 11:01:13
【问题描述】:

我已经开始使用 Appcelerator Hyperloop。虽然从零开始从 JS 访问原生 API 似乎很棒,但它确实引发了一些关于平台架构和性能的问题。

目前(AFAIK)Titanium 应用程序有一个主 UI 线程(运行本机 UI 控制器)和一个 JS 线程(运行 JS 逻辑)。从 JS 到 Native 的每个调用都通过“Bridge”(这是应用程序中的扩展操作)传递。

此外,Titanium API 并没有尽可能多地涵盖所有本机 API 和抽象。但如果引入新的 API,Appcelerator 可能需要一段时间才能将这些 API 实施到平台中。

我最喜欢 Titanium 的一个优点是能够对其进行扩展(iOS 使用 Objective-c,Android 使用 java)——允许使用 Titanium 未涵盖的原生 API,并在如果我们需要做任何对 JS 来说太“重”的事情。而且,如前所述,它是为每个平台 100% 原生开发的。

现在 Appcelerator 引入了 Hyperloop,我做了一个简单的测试应用,发现 Hyperloop 没有被翻译成原生代码,而只是被翻译成普通的 JS 代码:

var UILabel = require('hyperloop/uikit/uilabel');
var label = new UILabel();
label.text = "HELLO WORLD!";
$.index.add(label); 

另外一点就是你必须在主线程上运行。

因此,就 Hyperloop 架构而言,我们基本上想到了以下几点:

  1. 我们还有一座桥吗?如果 Hyperloop 是调用“特殊”Hyperloop 要求的 JS,那么我们还有一个桥,它现在不仅充当桥,还需要进行某种反射(这也是一种扩展操作)?
  2. 到目前为止,JS 在它自己的线程中运行 - 所以现在在单个主线程中运行似乎是更多 UI 阻塞操作的潜在来源。
  3. 老式模块是真正的原生模块(不包括桥接调用) - 那么启用 Hyperloop 的应用与那些相比如何?

目前还没有太多关于 Hyperloop 的文档或文章来解释其内部工作原理 - 因此,如果有人有任何答案,一直在尝试使用它的应用程序可能会非常有帮助。

【问题讨论】:

    标签: titanium appcelerator appcelerator-titanium appcelerator-hyperloop hyperloop


    【解决方案1】:

    直接回答您的问题:

    1. 不再涉及 Kroll-Proxies,因为实际类是在运行时生成的。这是通过使用进行反射的超循环元数据库(如您已经说过的)来构建一个 AST 来完成的,该 AST 可以获取实际的签名、类型、类、方法、属性等。
    2. 我们目前没有发现在主线程上运行时出现任何性能问题。如果您这样做,请提交 JIRA 票证,以便我们调查用例。
    3. 当时的旧模块“不那么原生”,仅仅是因为它们都被 Kroll 代理包裹(通过扩展来自 TiUIView 的每个视图和来自 TiProxy / TiViewProxy 的每个代理。Hyperloop 没有与这些一起工作,通过允许开发人员在他们的应用程序中实时测试他/她的过程,而无需手动打包和引用模块,从而使模块开发更快。Hyperloop 模块与已经使用的 CommonJS 模块没什么区别经常用于合金和其他钛组件。

    我希望这能让您快速了解 Hyperloop 的工作原理。如果您还有其他问题,请告诉我们!

    汉斯

    【讨论】:

    • 谢谢。事实上,我看到我得到的对象是KrollCallbackHyperloopClass。您能否进一步解释一下架构以及在主线程上运行意味着什么?在旧模块中,假设我创建了一个带有图像和文本的 TableView - 你所说的用 TiView 包装 TableView 是真的 - 但就该视图的子对象(ImageView $ Label)而言 - 它们是原生的一个是 - 您将它们绑定到的所有事件也是如此。只有你带回 JS 的东西才能过桥 - 那么它不是比反射更高效吗?
    • 你好!我对此做了自己的回答,因为 cmets 只能有 600 个字符。
    • @HansKnoechel 是否可以创建 Hyperloop 模块?我看到了你提出的规范,我想知道这方面的进展/计划如何。显然,人们想要即插即用模块,而不仅仅是每次都创建自定义的 Hyperloop 业务逻辑。
    • @droid-zilla 基本上,它只是一个 CommonJS 模块,带有一个额外的项目结构来正确管理资产。我不确定实现这一点的确切时间框架,但绝对应该添加一些内容,以便更轻松地创建可重用组件,尤其是直接从 CLI 和 Studio 中创建。
    【解决方案2】:

    (作为对上述评论的详细回答)

    假设您在 iOS 中有一个 tableview。本机类是UITableView,Titanium-API 是Ti.UI.TableView / Ti.UI.ListView

    虽然 ListView 通过将 Child-API 的使用抽象到模板中,与 TableView 相比已经提供了巨大的性能提升,但这些 child-API(Ti.UI.LabelTi.UI.ImageView,...)仍然是自定义类,它们是包装并提供自定义逻辑(!)例如跟踪它的父引用、内部数据结构和锁以在线程之间跳转。

    如果您现在检查本机 UITableViewHyperloop example,您可以直接访问本机 API,因此其背后的代理不需要管理部分、模板、项目等。当然,我们通过 kroll 代理提供该 API为了在 Titanium 中显示它,但您不会在从 SDK 进行的每次调用时“在桥之间跳转”。

    查看这一点的最简单方法是实际运行一些更大的示例,例如 tableview、collectionview 和 view-animation。如果您快速浏览这些内容,您已经感受到与“经典”Titanium API 相比的性能提升,仅仅是因为您的代理和(如您想要添加它的Ti.UI.Window)之间的唯一通信是.add()接收 HyperloopClass 类型的本机 API。

    最后,例如,使用Ti.UI.ListView 当然仍然有意义,因为它带有 Titanium 开发人员喜爱的内置实用程序(事件、简单的配置和布局处理)。但这也是 Hyperloop 的优势所在,它允许开发人员自己访问这些 API。

    我希望这有助于更多地理解它。

    【讨论】:

    • 谢谢。我想我在导致这个答案的问题中被误解了。我的意思是,如果我创建一个“经典”模块并创建一个 TableView(或任何与此相关的视图),那么容器视图的子元素和事件(这是唯一一个被 TiUIView 包裹的)都是原生的,未包装的,未反射的元素。所以理论上它们应该会产生更好的性能。
    • 明白了。是时候进行一些基准测试了 :-) 虽然我仍然认为与本机模块的任何交互都会再次通过更多的桥梁,因此 Hyperloop 会“获胜”。但这实际上需要测试。
    • 我认为这真的取决于模块以及模块和 JS 逻辑之间设计的通信是什么。让我们说是一个我们构建一个画廊的例子 - 模块加载图像,并响应点击事件,然后选择图像 - 在所有模块上,本机侧 - 只有当所选图像应该返回到js时,它才会返回js。因此,除了返回结果之外,所有交互都将是原生的——同样,这一切都取决于每个模块定义。
    • 我认为使用 Hyperloop 的最佳方式仍然是在 Native 代码中创建模块化库,然后通过 Hyperloop 公开它们。要求 JS 中的所有 Java 类然后创建我想要的类的想法似乎比仅使用 .aar 更乏味且容易出错。我看到这是可能的,我很高兴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多