成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Titanium架構(gòu)分析

移動(dòng)開(kāi)發(fā)
Titanium是一個(gè)Web應(yīng)用程序運(yùn)行環(huán)境,它支持不同的系統(tǒng)平臺(tái)(Windows、Linux、Mac),并且支持Web應(yīng)用程序?qū)Ρ镜谹PIs的訪問(wèn)。在基于Titanium平臺(tái)上,用戶可以快速開(kāi)發(fā)和方便的部署應(yīng)用程序,并且這些應(yīng)用程序可以使用本地APIs實(shí)現(xiàn)許多普通Web應(yīng)用程序無(wú)法完成的功能和特性。

一、分析的目標(biāo)

  • 了解Titanium產(chǎn)品的基本框架結(jié)構(gòu)和特點(diǎn)
  • 了解Titanium產(chǎn)品如何擴(kuò)展本地API以及訪問(wèn)方式
  • 了解Titanium產(chǎn)品中的動(dòng)態(tài)語(yǔ)言之間如何相互調(diào)用

二、Titanium概述

2.1 Titanium介紹

Titanium是一個(gè)Web應(yīng)用程序運(yùn)行環(huán)境,它支持不同的系統(tǒng)平臺(tái)(Windows、Linux、Mac),并且支持Web應(yīng)用程序?qū)Ρ镜谹PIs的訪問(wèn)。在基于Titanium平臺(tái)上,用戶可以快速開(kāi)發(fā)和方便的部署應(yīng)用程序,并且這些應(yīng)用程序可以使用本地APIs實(shí)現(xiàn)許多普通Web應(yīng)用程序無(wú)法完成的功能和特性。

2.2 Titanium特點(diǎn)

Titanium框架具有如下幾個(gè)方面的特點(diǎn):

  • 支持多平臺(tái)(Linux、Mac、Windows、移動(dòng)設(shè)備)
  • 使用Web技術(shù)加快軟件開(kāi)發(fā)速度
  • 支持Web中內(nèi)嵌多種編程語(yǔ)言
  • 支持對(duì)本地APIs的訪問(wèn)
  • 通過(guò)Appcelerator網(wǎng)絡(luò)云服務(wù),基于Titanium的應(yīng)用可以更容易的打包、測(cè)試和部署
  • 本地功能的模塊化,可動(dòng)態(tài)加載指定的功能模塊
  • 強(qiáng)大靈活的語(yǔ)言擴(kuò)展,用戶在Titanium框架中可以很方便的擴(kuò)展多種動(dòng)態(tài)語(yǔ)言

2.3 Titanium 框架結(jié)構(gòu)

上圖來(lái)自于Appcelerator官網(wǎng),該圖以iPhone和Android兩個(gè)移動(dòng)平臺(tái)為例,描述了Titanium的總體框架結(jié)構(gòu)。在Titanium框架中,Web應(yīng)用程序可以很方便的訪問(wèn)設(shè)備UI組件。比如,可以在頁(yè)面中使用Titanium提供的API控制導(dǎo)航條、工具欄、菜單,以及可以動(dòng)態(tài)的向用戶彈出對(duì)話框、警告框等。除此,之外Titanium API還支持本地功能模塊的訪問(wèn),即用戶可以使用Titanium提供的APIs接口訪問(wèn)數(shù)據(jù)庫(kù)、定位功能、文件系統(tǒng)功能、網(wǎng)絡(luò)功能、媒體功能等。

不過(guò)該框架圖,并沒(méi)有將Titanium中對(duì)多種腳本語(yǔ)言的相互訪問(wèn)機(jī)制很好的表現(xiàn)出來(lái)。但是,這一機(jī)制卻又是Titanium框架的一個(gè)比較重要的功能特性。

三、Titanium構(gòu)建

Titanium的構(gòu)建過(guò)程使用scons管理(http://www.scons.org/)。scons是一個(gè)開(kāi)源的軟件構(gòu)建工具,使用Python語(yǔ)言來(lái)描述軟件構(gòu)建規(guī)則。通過(guò)Titanium的源碼級(jí)構(gòu)建和Titanium的構(gòu)建規(guī)則兩個(gè)方面,可以了解Titanium運(yùn)行環(huán)境由那些部分組成、這些模塊和模塊之間的關(guān)系是什么。

[注]以下所有的測(cè)試和分析內(nèi)容均是以Linux平臺(tái)上Desktop版本的Titanium代碼為基礎(chǔ)。

構(gòu)建Titanium所依賴的庫(kù)和環(huán)境

  • Ruby 1.8.x 開(kāi)發(fā)包
  • Python 2.5.x開(kāi)發(fā)包
  • scons構(gòu)建工具
  • git 版本管理工具

Ubuntu 9.04上構(gòu)建Titanium所需的支持包

  1. sudo apt-get install build-essential ruby rubygems libzip-ruby \ 
  2. scons libxml2-dev libgtk2.0-dev python-dev ruby-dev \ 
  3. libdbus-glib-1-dev libnotify-dev libgstreamer0.10-dev \ 
  4. libxss-dev libcurl4-openssl-dev 
  5. sudo apt-get install git-core 

獲取Titanium源碼

  1. git clone git://github.com/marshall/titanium 
  2. cd titanium 

獲取Kroll源碼

  1. git submodule init 
  2. git submodule update 
  3. cd kroll 
  4. git checkout master 

構(gòu)建Titanium測(cè)試程序

  1. cd .. 
  2. scons debug=1 

運(yùn)行

  1. scons testapp debug=1 run=1 

有關(guān)Titanium構(gòu)建相關(guān)的信息,可以訪問(wèn)以下頁(yè)面獲得:

http://wiki.github.com/marshall/titanium/build-instructions

3.2 Titanium構(gòu)建規(guī)則分析

3.2.1 版本需求

構(gòu)建過(guò)程所需的庫(kù)/程序版本
Python 2.5
Ruby 1.8
Scons 1.2
kroll 源碼版本 12/30/99
titanium_desktop 源碼版本 12/30/99
WebKit版本 libwebkittitanium-1.0.so.2.7.0
   

3.2.2 默認(rèn)配置項(xiàng)

默認(rèn)配置項(xiàng)
配置 備注
PRODUCT_VERSION 0.7.0  
INSTALL_PREFIX /usr/local  
PRODUCT_NAME Titanium  
CONFIG_FILENAME tiapp.xml  
BUILD_DIR build  
THIRD_PARTY_DIR kroll/thirdparty  
DISTRIBUTION_URL api.appcelerator.net  
CRASH_REPORT_URL api.appcelerator.net/p/v1/app-crash-report  
GLOBAL_NS_VARNAME Titanium 定義了全局Titanium對(duì)象名稱
     

3.2.3 scons編譯參數(shù)

Scons編譯參數(shù)
debug 0表示release版本,1表示debug版本
clean 清除構(gòu)建的工程
qclean 清除構(gòu)建的工程
run 運(yùn)行TestApp
run_with 帶參數(shù)運(yùn)行TestApp,好像Linux平臺(tái)上沒(méi)用

3.2.4 構(gòu)建規(guī)則文件

構(gòu)建規(guī)則文件
kroll/SConscript.thirdparty Titanium所需的第三方支持文件規(guī)則
installation/SConscript Titanium安裝器構(gòu)建規(guī)則
kroll/SConscript 構(gòu)建kroll庫(kù)規(guī)則
modules/SConscript 構(gòu)建語(yǔ)言支持模塊規(guī)則
apps/SConscript 構(gòu)建TestApp規(guī)則
SConscript.dist 構(gòu)建SDK規(guī)則
SConscript.docs 構(gòu)建APIs文檔規(guī)則
SConscript.test 構(gòu)建測(cè)試程序規(guī)則

3.2.5 核心庫(kù)和程序構(gòu)建規(guī)則

庫(kù)/程序 規(guī)則
build/linux/runtime/template/kboot kroll/boot/breakpad/common/*.c

kroll/boot/breakpad/common/*.cc

kroll/boot/breakpad/client/*.cc

kroll/boot/breakpad/processor/*.cc

kroll/boot/breakpad/client/linux/handler/*.cc

kroll/boot/breakpad/common/linux/*.cc

build/linux/runtime/libkroll.so kroll/api/*.cpp

kroll/api/config/*.cpp

kroll/api/binding/*.cpp

kroll/api/utils/*.cpp

kroll/api/utils/poco/*.cpp

kroll/api/utils/linux/*.cpp

kroll/api/net/proxy_config.cpp

kroll/api/net/*_linux.cpp

build/linux/runtime/libkhost.so kroll/host/linux/host.cpp

kroll/host/linux/linux_job.cpp

/linux/modules/api/libapimodule.so poco third library(http://pocoproject.org/)

kroll/modules/api/*.cpp

build/linux/modules/javascript/libjavascriptmodule.so poco third library(http://pocoproject.org/)

webkittitanium-1.0 third library

kroll/modules/javascript/*.cpp

build/linux/modules/ruby/librubymodule.so poco third library(http://pocoproject.org/)

libruby third library

kroll/modules/ruby/*.cpp

build/linux/modules/php/libphpmodule.so poco third library(http://pocoproject.org/)

kroll/modules/php/*.cpp

   

四、Titanium靜態(tài)分析

該部分主要是說(shuō)明整個(gè)Titanium的閱讀工作量、弄清楚Titanium中定義的核心對(duì)象的功能作用,以及各個(gè)模塊之間的關(guān)系是什么。

4.1 代碼統(tǒng)計(jì)

這里,將Titanium項(xiàng)目代碼分成kroll和功能模塊擴(kuò)展兩部分代碼來(lái)統(tǒng)計(jì),數(shù)據(jù)如下兩表所示:

Kroll模塊代碼量統(tǒng)計(jì)
Language Files Blank Comment Code Scale Equiv
C/C++ Header 1168 35490
63506
111461
1.00
111461
HTML 386 1252 16112 51375 1.9 97612.5
C++ 162 6401 7046 33133 1.51 50030.83
Javascript 47 3273 1598 13214 1.48 19556.72
CSS 3 554 41 2720 1 2720
Object C 6 359 312 1400 2.96 4144
Python 10 260 185 1206 4.2 5065.2
Shell 11 56 157 234 3.81 891.54
Make 3 30 29 93 2.5 232.5
Assembly 1 15 39 57 0.25 14.25
Ruby 1 10 0 54 4.2 226.8
Yaml 1 0 0 12 0.9 10.8
SUM 1802 47938 89263 217012 1.35 293546.95
titanium_desktop模塊(排除Kroll模塊)
Language Files Blank Comment Code Scale Equiv
Javascript 118 5801 3276 28678 1.48 42443.44
C++ 125 4690 5169 27320 1.51 41253.2
C/C++ Header 159 1647 3443 7682 1 7682
HTML 49 347 39 3715 1.8 7058.5
Ruby 29 673 643 3227 4.2 13553.4
CSS 5 542 41 2655 1 2655
Python 45 601 664 2632 4.2 11054.4
C 1 167 237 1925 0.77 1482.25
Shell 13 60 158 251 3.81 956.31
PHP 5 37 1 179 3.5 626.5
XML 5 0 8 151 1.9 286.9
Object C 2 31 15 119 2.96 352.24
SUM 556 14596 13694 78534 1.65 129404.14

4.2 核心對(duì)象的介紹

對(duì)象 基類 說(shuō)明
AccessorBoundObject StaticBoundObject 對(duì)settergetter的封裝,當(dāng)用戶訪問(wèn)想訪問(wèn)XXX屬性時(shí),該對(duì)象會(huì)調(diào)用setXXX方法或者getXXX方法。目前Titanium中主要是JSTitanium對(duì)象使用AccessortBoundObject封裝
AccessorBoundMethod StaticBoundMethod 用于通過(guò)屬性的方式訪問(wèn)方法,由該對(duì)象封裝的方法,會(huì)自動(dòng)的導(dǎo)出settergetter方法
AccessorBoundList StaticBoundList 用于以屬性的方式訪問(wèn)list對(duì)象,由該對(duì)象封裝的list,會(huì)自動(dòng)導(dǎo)出settergetter
ArgList   對(duì)參數(shù)列表對(duì)象的封裝
Blob   對(duì)數(shù)據(jù)封裝,可以描述任何數(shù)據(jù)
Tuplex   對(duì)元組對(duì)象的封裝
DelegateStaticBoundObject KObject 用于對(duì)全局訪問(wèn)對(duì)象的封裝,目前Titanium中只有UITitanium JS對(duì)象使用該對(duì)象封裝
KList KObject 封裝List對(duì)象
KMethod KObject 對(duì)方法的封裝,所有擴(kuò)展語(yǔ)言的函數(shù),都需要用該對(duì)象封裝
KEventObject AccessorBoundObject 描述事件對(duì)象,JS中可以通過(guò)該對(duì)象,向主線程發(fā)送事件。比如重新載入頁(yè)面、彈出對(duì)話框。
KEventMethod KEventObject 對(duì)事件方法的封裝,目前只有ti.Process模塊使用該對(duì)象
KObject ReferenceCounted 所有的其他類型語(yǔ)言對(duì)象和方法都是繼承該類,這樣可以按照相同的方法處理不同語(yǔ)言對(duì)象和方法
StaticBoundList KList 靜態(tài)列表,使用內(nèi)部map綁定屬性
StaticBoundMethod KMethod 靜態(tài)方法
StaticBoundObject KObject 靜態(tài)對(duì)象,繼承該對(duì)象可以很方便的設(shè)置對(duì)象的屬性、方法。

每個(gè)StaticBoundObject內(nèi)部,都保存著一個(gè)StringShareValuemap成員屬性。

Value ReferenceCounted 描述對(duì)象類型
     

4.3 模塊之間的關(guān)系

從整體框架結(jié)構(gòu)上來(lái)看,可以將Titanium分成三個(gè)部分,最上層是WebKit以及針對(duì)WebKit的擴(kuò)展(修改很少),中間層是kroll可以將其看成是一個(gè)中間件,最下層是個(gè)個(gè)模塊的擴(kuò)展。模塊之間的關(guān)系如圖所示:

點(diǎn)擊查看大圖

以下從WebKit、Kroll和模塊擴(kuò)展三個(gè)部分來(lái)說(shuō)明

1、WebKit: 當(dāng)WebKit引擎解析頁(yè)面數(shù)據(jù)發(fā)現(xiàn)

首先,WebCore引擎會(huì)解析HTML頁(yè)面數(shù)據(jù),當(dāng)發(fā)現(xiàn)有標(biāo)簽,或者當(dāng)用戶觸發(fā)了頁(yè)面中某個(gè)與腳本函數(shù)相關(guān)的控件時(shí),WebCore會(huì)將相應(yīng)的腳本代碼片段傳遞給JavascriptCore解析執(zhí)行。如果對(duì)比Tinanium修改的WebKit代碼和原始的WebKit代碼(http://www.webkit.org)會(huì)發(fā)現(xiàn),tinanium對(duì)WebKit的修改是及小的。主要是作了兩個(gè)方面的工作:首先,tinanium擴(kuò)展了KURL的處理,增加了ti://, app://等私有協(xié)議的支持。再者,在WebKit/gtk/webkit/目錄中,添加了幾個(gè)接口函數(shù)(主要是用來(lái)處理擴(kuò)展的協(xié)議和注冊(cè)解析器),其中最重要的是webkit_titanium_add_script_evaluator,該接口在Kroll模塊的script類中會(huì)被調(diào)用,用來(lái)向WebKit引擎注冊(cè)一個(gè)Evaluator Proxy。

2、Kroll和Base Module:這部分主要的職責(zé)是負(fù)責(zé)Javascript的方法、對(duì)象和Python、Ruby、PHP等語(yǔ)言之間相互轉(zhuǎn)換、事件處理,以及模塊動(dòng)態(tài)加載。Kroll模塊中,定義了一個(gè)host對(duì)象,這個(gè)對(duì)象是整個(gè)TestApp的主線程,UI初始化、WebKit初始化和事件處理都是在host中完成的。host對(duì)象中保存了一個(gè)全局對(duì)象表,該表會(huì)在WebKit引擎、Python引擎、Ruby引擎之間以KObject中間對(duì)象形式相互傳遞,最終達(dá)到不同語(yǔ)言之間的相互調(diào)用。

3、API Extension:這里擴(kuò)展了大量的與系統(tǒng)平臺(tái)功能相關(guān)的API共Web應(yīng)用使用。其中最重要的一個(gè)對(duì)象是ti.UI,該模塊負(fù)責(zé)UI相關(guān)的資源、事件處理、GTK主界面的創(chuàng)建、Tininum JS對(duì)象的創(chuàng)建。

五、Titanium動(dòng)態(tài)分析

下面從6個(gè)方面以TestApp為例,來(lái)分析Titanium的主要特性和功能。

5.1 TestApp初始化

TestApp的啟動(dòng)過(guò)程有個(gè)自啟動(dòng)過(guò)程。首先,TestApp啟動(dòng)后會(huì)創(chuàng)建一個(gè)Application對(duì)象,該對(duì)象會(huì)從Mainifest文件中獲取App相關(guān)的資源,并且保存在一個(gè)全局變量中。然后,TestApp會(huì)設(shè)置幾個(gè)系統(tǒng)環(huán)境變量:

  • KR_BOOTSTRAPPED: 描述是否已經(jīng)初始化環(huán)境變量以及構(gòu)建Application對(duì)象
  • KR_HOME:描述運(yùn)行程序的HOME路徑
  • KR_RUNTIME:描述運(yùn)行時(shí)資源路徑
  • KR_MODULES:描述需加載模塊信息
  • LD_LIBRARY_PATH:描述模塊所在的文件夾路徑

***,TestApp會(huì)使用exec系統(tǒng)調(diào)用將自己自啟,然后通過(guò)之前設(shè)置 KR_BOOTSTRAPPED環(huán)境變量判斷是否進(jìn)入下一階段的初始化過(guò)程。如果 KR_BOOTSTRAPPED設(shè)置為YES,則會(huì)首先將其unset,然后啟動(dòng)LinuxHost。

在titanium框架中,使用動(dòng)態(tài)庫(kù)的方式將模塊之間的關(guān)系解耦合。在TestApp啟動(dòng)的第二階段中,StartHost(kroll/boot/boot_linux.cpp)會(huì)根據(jù)之前設(shè)置的 KR_RUNTIME路徑信息,找到libkhost.so動(dòng)態(tài)庫(kù),然后從libkhost.so中獲取Execute函數(shù)指針,并且調(diào)用(這里有個(gè)問(wèn)題,如果多個(gè)實(shí)列同時(shí)運(yùn)行,有可能KR_RUNTIME尚未unset就啟動(dòng)第二個(gè)應(yīng)用,則會(huì)出現(xiàn)TestApp異常)。

libkhost.so動(dòng)態(tài)庫(kù)中的Execute方法,首先創(chuàng)建一個(gè)Host實(shí)例,在這里是LinuxHost對(duì)象,然后調(diào)用該對(duì)象的Run方法進(jìn)入一個(gè)循環(huán)。這個(gè)循環(huán)是整個(gè)TestApp的主循環(huán),主要負(fù)責(zé)模塊的動(dòng)態(tài)發(fā)現(xiàn)和加載,事件處理。在LinuxHost的實(shí)現(xiàn)中,會(huì)維護(hù)一個(gè)job隊(duì)列,通過(guò)定時(shí)器的方式,每隔250ms的時(shí)間會(huì)去檢測(cè)該job隊(duì)列中是否有job存在(LinuxJob描述)。如果,事件存在則會(huì)一次性將所有的事件取出,并且清空事件隊(duì)列,然后一個(gè)個(gè)的執(zhí)行job對(duì)象的Execute方法。

TestApp的兩次初始化過(guò)程如下圖所示:

 

 

點(diǎn)擊查看大圖

5.2 模塊初始化

TestApp程序創(chuàng)建LinuxHost對(duì)象,并且執(zhí)行Run方法之后,會(huì)首先掃描KR_MODULES環(huán)境變量中指定的模塊,并且從 LD_LIBRARY_PATH定義的路徑信息中尋找到這些動(dòng)態(tài)庫(kù)模塊,并且加載(調(diào)用相應(yīng)模塊的Initialize方法)。LinuxHost首先加載的是基本模塊(API,PythonModule、RubyModule、PHPModule和JavascriptModule)。

以pythonModule為例,描述一個(gè)完整的加載過(guò)程:

  • Host::LoadModules從環(huán)境變量中獲取到python動(dòng)態(tài)庫(kù)的路徑信息
  • 調(diào)用Host::FindBasicModules方法,將libpythonmodule.so文件加載進(jìn)來(lái),然后調(diào)用PythonModule的Initialize方法
  • PythonModule::Initialize首先會(huì)向全局屬性表中創(chuàng)建一個(gè)Python和PythonEaluator對(duì)象的關(guān)聯(lián)。前面也說(shuō)到,Host對(duì)象會(huì)保存一個(gè)全局屬性表,這個(gè)表中使用KObject中間對(duì)象形式,將JAVASCRIPT、PYTHON、RUBY、PHP等語(yǔ)言定義的對(duì)象封裝,并且保存在該表中。運(yùn)行時(shí),可以使用Host對(duì)象的GetGlobalObject方法獲取。
  • 調(diào)用Script::AddScriptEvaluator靜態(tài)方法將PythonEvaluator對(duì)象放入Script對(duì)象中維護(hù)的一個(gè)Ealuator列表中。當(dāng)JavascriptCore引擎發(fā)現(xiàn)<script>標(biāo)簽會(huì)遍歷這個(gè)evaluator鏈表,通過(guò)MIME類型找到相應(yīng)的解析器實(shí)例,然后將代碼片段傳遞給相應(yīng)的解析器處理(這樣就可以支持HTML代碼中內(nèi)嵌多種語(yǔ)言)。

這里還有一個(gè)模塊比較特殊需要仔細(xì)說(shuō)明,即ti.UI模塊。該模塊負(fù)責(zé)WebKit引擎初始化,GTK窗口創(chuàng)建以及UI事件的處理。加載過(guò)程類似PythonModule,首先Host對(duì)象找到libtiuimodule.so動(dòng)態(tài)庫(kù),然后調(diào)用Initialize方法初始化,ti.UI模塊中的Initialize方法只做了兩件事情,創(chuàng)建了一個(gè)APIBinding對(duì)象,然后將“API”屬性和APIBinding關(guān)聯(lián)起來(lái),保存在全局屬性表中。接下來(lái),當(dāng)Host::LoadModules方法加載完畢所有的動(dòng)態(tài)庫(kù)后,會(huì)調(diào)用Host::StartModules來(lái)啟動(dòng)模塊(在整個(gè)TestApp運(yùn)行中,只有ti.UI模塊的Start方法被重載了,而其他模塊在StartModules方法被執(zhí)行時(shí),什么事情都沒(méi)有做)。UIModule::Start方法做了三個(gè)非常重要的操作:1、創(chuàng)建GtkUIBinding對(duì)象,并且將“UI”和該對(duì)象綁定,存放在全局屬性表中。2、調(diào)用ScriptEvaluator::Initialzie()使用WebKit擴(kuò)展中導(dǎo)出的webkit_titanium_add_script_evaluator函數(shù),將自己注冊(cè)到JavascriptCore中。3、創(chuàng)建初始化WebView。

至此,WebKit引擎已經(jīng)初始化完畢、UI界面已經(jīng)初始化完畢、相應(yīng)語(yǔ)言的解析器以及JAVACRIPT API擴(kuò)展對(duì)象已經(jīng)添加到全局屬性表中。但是至此,頁(yè)面中是無(wú)法正常訪問(wèn)Titanium對(duì)象的。

整個(gè)過(guò)程如下圖所示:

 

 

點(diǎn)擊查看大圖

5.3 Titanium對(duì)象的注冊(cè)

Javascript中的Titanium并沒(méi)有通過(guò)硬編碼的方式定義該名稱,而是在構(gòu)建的過(guò)程中通過(guò)變量的方式指定的。在構(gòu)建規(guī)則中有GLOBAL_NS_VARNAME變量,該變量名稱會(huì)作為編譯參數(shù)傳遞,代碼通過(guò)改變量的定義,來(lái)確定Javascript可見(jiàn)的Titanium主對(duì)象的名稱是什么。

當(dāng)webView構(gòu)建完畢后,Titanium Js主對(duì)象并不存在,只有當(dāng)***次WebKit遇到腳本代碼時(shí),這個(gè)對(duì)象才被創(chuàng)建。當(dāng)WebKit引擎碰到腳本對(duì)象時(shí),會(huì)調(diào)用JavascriptCore的initScipt方法,初始化Javascript引擎。在此JavascriptCore會(huì)將我們之前調(diào)用webkit_titanium_add_script_evaluator增加的Evaluator代理和JavascriptCore解析關(guān)聯(lián)起來(lái)。當(dāng)引擎和資源都初始化完畢,會(huì)向FrameClient發(fā)送object avaliable通知,會(huì)調(diào)用FrameLoader::dispatchWindowObjectAvaliable()方法。這個(gè)方法會(huì)導(dǎo)致UserWindow::RegisterJSContext()方法的調(diào)用。然后UserWindow對(duì)象會(huì)創(chuàng)建一個(gè)DelegateStaticBoundObject對(duì)象來(lái)描述Titanium對(duì)象,并且將之前初始化完畢的Titanium API對(duì)象(KObject)與Titanium對(duì)象關(guān)聯(lián)起來(lái),然后將其放入到全局屬性表中。這樣,之后Web應(yīng)用程序就可以從全局屬性表中訪問(wèn)到Titanium對(duì)象了。但是Titanium對(duì)象中有哪些子屬性是不知道的,這是運(yùn)行時(shí)才去確定。

這個(gè)初始化過(guò)程如下圖所示:

 

 

點(diǎn)擊查看大圖

5.4 事件系統(tǒng)

Titanium的事件系統(tǒng)分成兩個(gè)部分來(lái)說(shuō)明,一部分是如何獲取事件,另一部分是如何向事件系統(tǒng)中增加新事件。

當(dāng)linuxHost::RunLoop循環(huán)被調(diào)用后,立即會(huì)注冊(cè)一個(gè)定時(shí)器,每隔250ms調(diào)用一次main_thread_job_handler函數(shù)。該函數(shù)首先通過(guò)GetJobs方法獲取當(dāng)前系統(tǒng)中未處理的事件,并且依次的調(diào)用事件對(duì)象(LinuxJob)的Execute方法執(zhí)行。如果系統(tǒng)沒(méi)有未決的事件存在,則立即返回。

事件的添加和觸發(fā)均通過(guò)LinuxHost::InvokeMethodOnMainThread()方法完成。該函數(shù)會(huì)創(chuàng)建一個(gè)LinuxJob對(duì)象,并且插入到事件隊(duì)列尾中。事件的觸發(fā)有多種可能性,可以是由Javascript代碼觸發(fā),也可以是內(nèi)部事件觸發(fā),同樣也有可能是UI事件觸發(fā)。

由于Titanium擴(kuò)展的JS API在C層上都會(huì)與相應(yīng)的C方法對(duì)應(yīng),當(dāng)Web應(yīng)用程序調(diào)用相應(yīng)的JS方法,對(duì)應(yīng)的C方法會(huì)被調(diào)用,該方法則會(huì)使用LinuxHost::InvokeMethodOnMainThread()方法,向主線程發(fā)送事件處理請(qǐng)求。

對(duì)于UI來(lái)說(shuō),在Linux平臺(tái)上所有的UI相關(guān)的事件首先是被GTK的應(yīng)用框架截獲,當(dāng)有UI事件到來(lái)時(shí),ti.UI模塊會(huì)創(chuàng)建對(duì)應(yīng)事件的KEvent對(duì)象(在event.h中定義),然后調(diào)用KEvent對(duì)象的Fire方法,觸發(fā)事件。該方法會(huì)間接的使用LinuxHost::InvokeMethodOnMainThread方法向LinuxHost事件隊(duì)列注冊(cè)事件。

這個(gè)過(guò)程如下圖所示:

 

 

點(diǎn)擊查看大圖

5.5 訪問(wèn)Titanium對(duì)象屬性和方法

比如,有一段Javascript腳本中調(diào)用Titanium.API獲取Titanium對(duì)象的API屬性,當(dāng)JavascriptCore解析到這部分代碼時(shí),并不知道這個(gè)對(duì)象是什么類型的,完全當(dāng)作一個(gè)抽象的JSValue對(duì)象來(lái)對(duì)待,因?yàn)閷?duì)于Javascript引擎來(lái)說(shuō),并不需要時(shí)刻知道對(duì)象是什么,有那些屬性和方法,只有到運(yùn)行時(shí)才會(huì)去用查詢?cè)搶?duì)象中是否存在指定的屬性或者方法(JavascriptCore內(nèi)部維護(hù)了一張屬性表,通過(guò)查詢方式獲取相應(yīng)屬性或者函數(shù)的處理函數(shù)指針。這點(diǎn)V8做的就比較高明,用類的方式描述,動(dòng)態(tài)將對(duì)應(yīng)JS的方法和屬性轉(zhuǎn)換成C++的成員函數(shù)和成員變量,大量的減少了訪問(wèn)時(shí)間)。由于API這個(gè)對(duì)象是由Kroll創(chuàng)建的,是一個(gè)KObject對(duì)象,在掛載到Javascript 全局屬性表之前,Titanium會(huì)調(diào)用KObjectToJSValue方法,將KObject對(duì)象轉(zhuǎn)換成一個(gè)JS的Object對(duì)象,并且設(shè)置了幾個(gè)比較重要的回調(diào)函數(shù):

  • HasPropertyCallback: 當(dāng)查詢屬性時(shí)候被調(diào)用
  • GetPropertyCallback: 當(dāng)獲取指定屬性時(shí)被調(diào)用
  • SetPropertyCallback: 當(dāng)設(shè)置指定屬性時(shí)被調(diào)用

當(dāng)javascript訪問(wèn)用Titanium對(duì)象的API屬性時(shí),通過(guò)JSValue.Get方法會(huì)調(diào)用到GetPropertyCallback函數(shù),該函數(shù)會(huì)查詢KObject對(duì)象中(這里是說(shuō)的Titanium)是否有API這個(gè)屬性,如果有則轉(zhuǎn)換成JSValue對(duì)象,并且返回給Javascript引擎。

如果這里訪問(wèn)的是一個(gè)屬性的方法,過(guò)程和訪問(wèn)對(duì)象是一樣的,只不過(guò)***創(chuàng)建的是一個(gè)Function Js對(duì)象,而非Object對(duì)象。當(dāng)Javascript訪問(wèn)這個(gè)返回的Function對(duì)象時(shí),Javascript引擎會(huì)調(diào)用callAsFunction方法,而該方法會(huì)引發(fā)CallAsFunctionCallback回調(diào)函數(shù)被調(diào)用(該函數(shù)是靜態(tài)函數(shù)在KMethodToJSValue函數(shù)中注冊(cè))。這樣通過(guò)CallAsFunctionCallback這個(gè)回調(diào)接口,調(diào)用實(shí)際的KObject的Call方法,執(zhí)行實(shí)際的處理函數(shù)。

屬性訪問(wèn)過(guò)程如下圖所示:

 

 

點(diǎn)擊查看大圖

5.6 Javascript、Python、Ruby動(dòng)態(tài)語(yǔ)言間的相互調(diào)用

Titanium框架中引入了一個(gè)比較有意思的特性,即支持多種語(yǔ)言之間的相互調(diào)用。從實(shí)現(xiàn)技術(shù)角度來(lái)說(shuō),Titanium的多語(yǔ)言支持的設(shè)計(jì)思想,是在學(xué)習(xí)了WebKit的Binding機(jī)制而發(fā)展過(guò)來(lái)的。主要用到了JavascriptCore引擎可以動(dòng)態(tài)注冊(cè)Evaluator的機(jī)制。HTML語(yǔ)言中定義了<script>標(biāo)簽,用于內(nèi)嵌腳本語(yǔ)言,該標(biāo)簽有個(gè)子屬性type,通過(guò)該屬性可以讓瀏覽器引擎區(qū)分是什么類型的腳本。加入我們有如下的腳本代碼:

  1. <script type=”text/python” src=”xxx.py”></script> 

首先,WebCore引擎會(huì)解析HTML頁(yè)面數(shù)據(jù),當(dāng)發(fā)現(xiàn)有<script>標(biāo)簽出現(xiàn),則會(huì)創(chuàng)建HTMLScriptElement,對(duì)于script有兩種處理情況,一種是如上代碼通過(guò)src包含一個(gè)腳本路徑,還有一種情況是定義一段代碼,通過(guò)控件或者超連接的方式以事件方式觸發(fā)。如果是***種情況,則會(huì)在創(chuàng)建HTMLScriptElement的時(shí)引發(fā)ScriptElementData::requestScript方法的調(diào)用。如果是第二種情況,則會(huì)在觸發(fā)相應(yīng)事件時(shí)候調(diào)用FrameLoader::executeScript方法執(zhí)行腳本。最終都會(huì)調(diào)用JavascriptCore中的EvaluatorAdapter::evaluate()。由于在初始化ti.UI模塊時(shí),我們已經(jīng)注冊(cè)了自己的evaluator(ScriptEvaluator),因此會(huì)將獲取的腳本信息傳遞給ScriptEvaluator,在該對(duì)象中,會(huì)通過(guò)Script::Evaluate()方法,根據(jù)傳遞下來(lái)腳本的MIME類型(也就是script中text字段定義的類型)派發(fā)給注冊(cè)的不同解析器去執(zhí)行。

這里以Javascript調(diào)用Python代碼,并且Python代碼中又調(diào)用了ruby代碼為例子說(shuō)明其調(diào)用過(guò)程。

Python代碼:

  1. def abc(): 
  2. ruby_fun() 

Ruby代碼:

  1. def ruby_func() 
  2. … 
  3. end 

當(dāng)pythonEvaluator::Evaluate()被調(diào)用后,首先將保存的全局JS對(duì)象表轉(zhuǎn)換成Python可識(shí)別的對(duì)象字典(KMethodToPyObject完成,轉(zhuǎn)換成PyKMethodType的Python對(duì)象)。這樣在之后編譯的Python代碼中就可以訪問(wèn)到這些對(duì)象。然后將Python代碼使用Python編譯器編譯,并且將編譯后的函數(shù)對(duì)象轉(zhuǎn)換成KObject對(duì)象,插入到全局的JS對(duì)象表中(abc)。這樣,Javscript,和其他語(yǔ)言都可以識(shí)別該對(duì)象。同樣,對(duì)Ruby函數(shù)的處理,也會(huì)首先將全局JS對(duì)象表中的KObject對(duì)象轉(zhuǎn)換成Ruby的對(duì)象,然后對(duì)Ruby函數(shù)進(jìn)行編譯,將新生成的Ruby函數(shù)對(duì)象(ruby_fun)轉(zhuǎn)換成KObject對(duì)象,然后從新更新JS全局對(duì)象轉(zhuǎn)換表。至此,全局JS對(duì)象表中就新增了兩個(gè)KObject對(duì)象:ruby_fun, abc。

當(dāng)javascript訪問(wèn)該abc函數(shù)對(duì)象時(shí),按照通常方式首先調(diào)用CaAsFunctionCallback,該函數(shù)會(huì)調(diào)用KObject的Call方法,由于該KObject實(shí)際上就是一個(gè)KPythonMethod對(duì)象,因此KPythonMethod對(duì)象的Call方法會(huì)被調(diào)用。之前我們注冊(cè)的Python方法是一個(gè)PyKMethodType,該類型中定義了一個(gè)方法回調(diào)函數(shù),當(dāng)Python方法被調(diào)用時(shí),該回調(diào)函數(shù)(PyKMethod_call)會(huì)被調(diào)用。這個(gè)例子中,在Python代碼里調(diào)用了ruby_fun,因此當(dāng)PyKMethod_call被調(diào)用時(shí),首先將調(diào)用的KObject對(duì)象(實(shí)際上是一個(gè)對(duì)Ruby函數(shù)對(duì)象的封裝)轉(zhuǎn)換成KMethod對(duì)象,然后調(diào)用Call方法。這樣就通過(guò)間接調(diào)用,調(diào)用到KRubyMethod的Call方法,使得Ruby函數(shù)得到執(zhí)行。

整個(gè)過(guò)程如下圖所示:

 

 

點(diǎn)擊查看大圖

六、參考資源

http://www.appcelerator.com/

責(zé)任編輯:佚名 來(lái)源: 姜江的博客
相關(guān)推薦

2012-04-19 17:16:32

Titanium實(shí)例代碼分析

2012-05-18 11:29:55

Titaniumpros

2012-05-18 11:34:03

Titaniumcons

2012-04-20 11:07:12

Titanium

2012-06-26 10:40:43

Titanium

2012-04-19 12:58:26

TitaniumJSS

2012-04-19 13:55:19

TitaniumTiMVC

2012-05-17 09:09:05

Titanium單元測(cè)試

2012-06-14 09:42:20

跨平臺(tái)工具AppceleratoTitanium

2012-04-19 13:52:16

TitaniumMVCRedux

2012-04-19 16:22:12

TitaniumTabGroup

2012-05-23 09:41:37

Titanium St卸載

2012-05-18 11:28:57

TitaniumCommunity W

2012-05-23 09:28:14

Titanium錯(cuò)誤應(yīng)對(duì)辦法

2012-05-18 10:08:56

TitaniumAndroid

2012-04-19 16:41:24

Titanium視頻實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)

2012-05-23 09:33:37

TitaniumStudioAndroid APK

2012-04-19 11:40:21

Titanium

2012-05-23 09:46:15

Titanium MoTitanium

2012-05-18 11:16:42

@Kroll注解詳解TitaniumAndroid模塊
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲人在线 | 久久久www成人免费无遮挡大片 | 成人免费观看网站 | 精品99在线| 一区二区三区四区在线视频 | 国产亚洲精品久久午夜玫瑰园 | 日日碰狠狠躁久久躁婷婷 | 中文字幕一区二区三区四区五区 | 天天操天天干天天爽 | 久久久久国产精品午夜一区 | 中文字幕亚洲免费 | 亚洲午夜小视频 | 99在线免费视频 | 乱一性一乱一交一视频a∨ 色爱av | 337p日本欧洲亚洲大胆 | 成人午夜免费福利视频 | 国产视频1区 | 九九国产在线观看 | 免费视频二区 | 伊人伊人 | 日韩精品在线视频免费观看 | 亚洲国产欧美国产综合一区 | 亚洲一区在线日韩在线深爱 | 国产女人叫床高潮大片免费 | 日韩欧美视频网站 | 免费在线视频一区二区 | 日韩影院一区 | 欧美日韩国产高清 | 久久久蜜臀国产一区二区 | 欧美日韩国产一区二区三区 | 精品国产一区二区三区免费 | 一区二区日本 | 日本精品一区二区三区在线观看视频 | 亚洲成人中文字幕 | 日韩精品一区二区三区免费观看 | 97视频久久| 夜夜爽99久久国产综合精品女不卡 | 欧美日韩精品一区二区三区四区 | 欧美成视频 | 天天射夜夜操 | 国产精品久久久久久久午夜片 |