Back

Titanium 进阶: module , proxy, view proxy 与 view

发布时间: 2016-01-07 02:16:00

refer to:  http://docs.appcelerator.com/platform/latest/#!/guide/Titanium_Module_Concepts

titanium中的module有下面几种:

1. built-in module: 内置的module ,包括: Ti.UI,  Ti.Geolocation , 这种module在任何时候titanium系统中都可以用(不用require)

2. native module , 也叫packaged module: 使用require才能调用的module, 例如: ti.cloud   .  这种module就是广泛意义的module

3. common js module.

我们接下来要说的module, 就是 native/packaged module , 调用第三方库的native code ,全靠它。

下面是几个概念:

Proxy

定义: 是一个包含js方法的对象。( a native object exposes a javascript API) 

Ti.UI.Button 就是一个proxy, 它调用了 安卓和ios中的 native button。 下面就是例子:

// 1. 创建一个 proxy object
var win = Ti.UI.createWindow(); 
// 2. 设置属性 properties
win.title = "Hello World";
// 3. 调用proxy的 open方法
win.open(); 

下图是对上图过程的说明:

Create Proxy

虽然 上面的 win 看起来是一个普通的js object ,但是实际上有两个object:  js  object, 与 native code中的proxy object

所以,如果native proxy 中,没有一个叫 'color' 的方法,而 js object有这个方法的话,那么下面的代码:

var win = Ti.UI.createWindow();
win.color = 'red';    // 这个color 方法,只被 js object 调用
win.title = 'hello, title!';    // 这个title方法,因为同时被两个object具备,所有会被同时在两个不同的objec上调用。

Native Module Objects 

这个就是我们 ti create module时, 建立了两个文件: xxProxy 与 xxModule , 中的module文件。

一个packaged module中,只能有一个module 文件。 (xxModule.java)

一个proxy 只能有一个 parent module (是不是一个parent module可以对应多个proxy ?)  例如, Ti.UI.createButton 就对应了Ti.UI.Button 对象( 前者方法创建了后者)

Views and View Proxies

For UI components, there are some additional classes you'll need to use. A view proxy is a special proxy type that extends TiViewProxy, which has additional properties and methods specific to the Titanium UI system. Each view proxy has a corresponding Titanium view type, which extends the TiUIView class. The view proxy provides a way for applications to interact with the view from JavaScript. The view object itself may be created and destroyed as needed – for example, the controls in a window don't need to be instantiated until the window is opened.

view proxy 是特殊的proxy (extends TiViewProxy ) 每个view proxy都对应了一个titanium view type( extends TiUIView).

view proxy 让我们可以通过js代码调用view. 

(native? ) view 可以被我们创建或者销毁。

所以有几点要注意:

1. 当你为view proxy设置某个属性值时, 对应的native view可能还没创建

2. 如果某个native view 被创建时,它肯定使用了对应的view proxy的已经设置好了的属性

3. view proxy中的属性一变化,对应的native view的属性也发生变化。

从 js object到 native object的转换

数据类型可以从js到 native, 也可以从native 的类型换成js

1. 普通的类型,比如:数字,字符串等,在js, java, object c中都有对应的转换方式

2. 复杂类型,比如: js中的object, 转换成java 就是hash, 转换成ob 就是 NSDictionary

3. 更复杂的类型,可以通过 js proxy进行进一步的转换

Events and Callbacks

events 是事件,

callbacks:回调函数。

他们都可以在 异步调用时被用到。events 更加灵活些,因为一个events可以被多个listener响应。而callback 只是一个function

Threading  进程

JavaScript is inherently single-threaded; it provides no mechanisms for synchronizing between multiple threads. However, the native platforms support multiple threads. In both iOS and Android, an application has a single main thread (or UI thread), which is the only thread allowed to interact with native UI elements. This thread is separate from the JavaScript runtime thread, so both iOS and Android provide methods for executing code on the main thread. Doing anything time-consuming on the UI thread can cause the UI to freeze up, so you should only use the UI thread when necessary:

javascript 是单进程,它不支持多进程。但是对于native platform则支持多进程。 在ios 和 安卓上,一个app,有一个 主进程(或者叫UI进程),该进程允许与 NATIVE UI 元素做交互。 该进程与 javascript runtime是隔离的. 所以,该进程提供了对应的方法来解决这个问题。 但是,调用这类的方法,会让主进程卡住,所以,我们对这类UI 进程中的方法,只在必要时使用: 

Use the UI thread when directly manipulating native UI elements.
Avoid blocking the UI thread for any reason.

所以,我们要尽量使用 callback ,来避免卡死主进程的问题。

On the iOS platform, each JavaScript context operates in its own thread. If you create a Window using the url property, the window runs in a separate context and in a separate thread. For this reason, when communicating between JavaScript contexts on iOS, you should only pass serializable JavaScript objects, not functions or proxy objects.

在ios平台中,每个js context都运行在一个单独的进程中。如果你使用url来创建了一个window, 那么这个window就运行在了一个独立的context/进程中。所以,如果在 ios中的不同js context中通讯时,应该只传递 序列化的 js对象,而不是 function 或者 proxy object.

When calling a callback from a module, the callback is invoked on the appropriate JavaScript runtime thread. When you fire an event from your module, the event listener function is called on the thread where the listener was added. (Potentially, this means that the same event could be delivered on multiple threads if your application has multiple contexts, each with a listener defined for that event.)

在module中调用一个callback的话,该 callback是在 某个恰当的 js runtime进程中运行的。

调用一个 event的话,该event listener运行在它在被“声明”(was added) 的那个进程中。

Back