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

Titanium架構分析

移動開發
Titanium是一個Web應用程序運行環境,它支持不同的系統平臺(Windows、Linux、Mac),并且支持Web應用程序對本地APIs的訪問。在基于Titanium平臺上,用戶可以快速開發和方便的部署應用程序,并且這些應用程序可以使用本地APIs實現許多普通Web應用程序無法完成的功能和特性。

一、分析的目標

  • 了解Titanium產品的基本框架結構和特點
  • 了解Titanium產品如何擴展本地API以及訪問方式
  • 了解Titanium產品中的動態語言之間如何相互調用

二、Titanium概述

2.1 Titanium介紹

Titanium是一個Web應用程序運行環境,它支持不同的系統平臺(Windows、Linux、Mac),并且支持Web應用程序對本地APIs的訪問。在基于Titanium平臺上,用戶可以快速開發和方便的部署應用程序,并且這些應用程序可以使用本地APIs實現許多普通Web應用程序無法完成的功能和特性。

2.2 Titanium特點

Titanium框架具有如下幾個方面的特點:

  • 支持多平臺(Linux、Mac、Windows、移動設備)
  • 使用Web技術加快軟件開發速度
  • 支持Web中內嵌多種編程語言
  • 支持對本地APIs的訪問
  • 通過Appcelerator網絡云服務,基于Titanium的應用可以更容易的打包、測試和部署
  • 本地功能的模塊化,可動態加載指定的功能模塊
  • 強大靈活的語言擴展,用戶在Titanium框架中可以很方便的擴展多種動態語言

2.3 Titanium 框架結構

上圖來自于Appcelerator官網,該圖以iPhone和Android兩個移動平臺為例,描述了Titanium的總體框架結構。在Titanium框架中,Web應用程序可以很方便的訪問設備UI組件。比如,可以在頁面中使用Titanium提供的API控制導航條、工具欄、菜單,以及可以動態的向用戶彈出對話框、警告框等。除此,之外Titanium API還支持本地功能模塊的訪問,即用戶可以使用Titanium提供的APIs接口訪問數據庫、定位功能、文件系統功能、網絡功能、媒體功能等。

不過該框架圖,并沒有將Titanium中對多種腳本語言的相互訪問機制很好的表現出來。但是,這一機制卻又是Titanium框架的一個比較重要的功能特性。

三、Titanium構建

Titanium的構建過程使用scons管理(http://www.scons.org/)。scons是一個開源的軟件構建工具,使用Python語言來描述軟件構建規則。通過Titanium的源碼級構建和Titanium的構建規則兩個方面,可以了解Titanium運行環境由那些部分組成、這些模塊和模塊之間的關系是什么。

[注]以下所有的測試和分析內容均是以Linux平臺上Desktop版本的Titanium代碼為基礎。

構建Titanium所依賴的庫和環境

  • Ruby 1.8.x 開發包
  • Python 2.5.x開發包
  • scons構建工具
  • git 版本管理工具

Ubuntu 9.04上構建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 

構建Titanium測試程序

  1. cd .. 
  2. scons debug=1 

運行

  1. scons testapp debug=1 run=1 

有關Titanium構建相關的信息,可以訪問以下頁面獲得:

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

3.2 Titanium構建規則分析

3.2.1 版本需求

構建過程所需的庫/程序版本
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 默認配置項

默認配置項
配置 備注
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對象名稱
     

3.2.3 scons編譯參數

Scons編譯參數
debug 0表示release版本,1表示debug版本
clean 清除構建的工程
qclean 清除構建的工程
run 運行TestApp
run_with 帶參數運行TestApp,好像Linux平臺上沒用

3.2.4 構建規則文件

構建規則文件
kroll/SConscript.thirdparty Titanium所需的第三方支持文件規則
installation/SConscript Titanium安裝器構建規則
kroll/SConscript 構建kroll庫規則
modules/SConscript 構建語言支持模塊規則
apps/SConscript 構建TestApp規則
SConscript.dist 構建SDK規則
SConscript.docs 構建APIs文檔規則
SConscript.test 構建測試程序規則

3.2.5 核心庫和程序構建規則

/程序 規則
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靜態分析

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

4.1 代碼統計

這里,將Titanium項目代碼分成kroll和功能模塊擴展兩部分代碼來統計,數據如下兩表所示:

Kroll模塊代碼量統計
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 核心對象的介紹

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

每個StaticBoundObject內部,都保存著一個StringShareValuemap成員屬性。

Value ReferenceCounted 描述對象類型
     

4.3 模塊之間的關系

從整體框架結構上來看,可以將Titanium分成三個部分,最上層是WebKit以及針對WebKit的擴展(修改很少),中間層是kroll可以將其看成是一個中間件,最下層是個個模塊的擴展。模塊之間的關系如圖所示:

點擊查看大圖

以下從WebKit、Kroll和模塊擴展三個部分來說明

1、WebKit: 當WebKit引擎解析頁面數據發現

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

2、Kroll和Base Module:這部分主要的職責是負責Javascript的方法、對象和Python、Ruby、PHP等語言之間相互轉換、事件處理,以及模塊動態加載。Kroll模塊中,定義了一個host對象,這個對象是整個TestApp的主線程,UI初始化、WebKit初始化和事件處理都是在host中完成的。host對象中保存了一個全局對象表,該表會在WebKit引擎、Python引擎、Ruby引擎之間以KObject中間對象形式相互傳遞,最終達到不同語言之間的相互調用。

3、API Extension:這里擴展了大量的與系統平臺功能相關的API共Web應用使用。其中最重要的一個對象是ti.UI,該模塊負責UI相關的資源、事件處理、GTK主界面的創建、Tininum JS對象的創建。

五、Titanium動態分析

下面從6個方面以TestApp為例,來分析Titanium的主要特性和功能。

5.1 TestApp初始化

TestApp的啟動過程有個自啟動過程。首先,TestApp啟動后會創建一個Application對象,該對象會從Mainifest文件中獲取App相關的資源,并且保存在一個全局變量中。然后,TestApp會設置幾個系統環境變量:

  • KR_BOOTSTRAPPED: 描述是否已經初始化環境變量以及構建Application對象
  • KR_HOME:描述運行程序的HOME路徑
  • KR_RUNTIME:描述運行時資源路徑
  • KR_MODULES:描述需加載模塊信息
  • LD_LIBRARY_PATH:描述模塊所在的文件夾路徑

***,TestApp會使用exec系統調用將自己自啟,然后通過之前設置 KR_BOOTSTRAPPED環境變量判斷是否進入下一階段的初始化過程。如果 KR_BOOTSTRAPPED設置為YES,則會首先將其unset,然后啟動LinuxHost。

在titanium框架中,使用動態庫的方式將模塊之間的關系解耦合。在TestApp啟動的第二階段中,StartHost(kroll/boot/boot_linux.cpp)會根據之前設置的 KR_RUNTIME路徑信息,找到libkhost.so動態庫,然后從libkhost.so中獲取Execute函數指針,并且調用(這里有個問題,如果多個實列同時運行,有可能KR_RUNTIME尚未unset就啟動第二個應用,則會出現TestApp異常)。

libkhost.so動態庫中的Execute方法,首先創建一個Host實例,在這里是LinuxHost對象,然后調用該對象的Run方法進入一個循環。這個循環是整個TestApp的主循環,主要負責模塊的動態發現和加載,事件處理。在LinuxHost的實現中,會維護一個job隊列,通過定時器的方式,每隔250ms的時間會去檢測該job隊列中是否有job存在(LinuxJob描述)。如果,事件存在則會一次性將所有的事件取出,并且清空事件隊列,然后一個個的執行job對象的Execute方法。

TestApp的兩次初始化過程如下圖所示:

 

 

點擊查看大圖

5.2 模塊初始化

TestApp程序創建LinuxHost對象,并且執行Run方法之后,會首先掃描KR_MODULES環境變量中指定的模塊,并且從 LD_LIBRARY_PATH定義的路徑信息中尋找到這些動態庫模塊,并且加載(調用相應模塊的Initialize方法)。LinuxHost首先加載的是基本模塊(API,PythonModule、RubyModule、PHPModule和JavascriptModule)。

以pythonModule為例,描述一個完整的加載過程:

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

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

至此,WebKit引擎已經初始化完畢、UI界面已經初始化完畢、相應語言的解析器以及JAVACRIPT API擴展對象已經添加到全局屬性表中。但是至此,頁面中是無法正常訪問Titanium對象的。

整個過程如下圖所示:

 

 

點擊查看大圖

5.3 Titanium對象的注冊

Javascript中的Titanium并沒有通過硬編碼的方式定義該名稱,而是在構建的過程中通過變量的方式指定的。在構建規則中有GLOBAL_NS_VARNAME變量,該變量名稱會作為編譯參數傳遞,代碼通過改變量的定義,來確定Javascript可見的Titanium主對象的名稱是什么。

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

這個初始化過程如下圖所示:

 

 

點擊查看大圖

5.4 事件系統

Titanium的事件系統分成兩個部分來說明,一部分是如何獲取事件,另一部分是如何向事件系統中增加新事件。

當linuxHost::RunLoop循環被調用后,立即會注冊一個定時器,每隔250ms調用一次main_thread_job_handler函數。該函數首先通過GetJobs方法獲取當前系統中未處理的事件,并且依次的調用事件對象(LinuxJob)的Execute方法執行。如果系統沒有未決的事件存在,則立即返回。

事件的添加和觸發均通過LinuxHost::InvokeMethodOnMainThread()方法完成。該函數會創建一個LinuxJob對象,并且插入到事件隊列尾中。事件的觸發有多種可能性,可以是由Javascript代碼觸發,也可以是內部事件觸發,同樣也有可能是UI事件觸發。

由于Titanium擴展的JS API在C層上都會與相應的C方法對應,當Web應用程序調用相應的JS方法,對應的C方法會被調用,該方法則會使用LinuxHost::InvokeMethodOnMainThread()方法,向主線程發送事件處理請求。

對于UI來說,在Linux平臺上所有的UI相關的事件首先是被GTK的應用框架截獲,當有UI事件到來時,ti.UI模塊會創建對應事件的KEvent對象(在event.h中定義),然后調用KEvent對象的Fire方法,觸發事件。該方法會間接的使用LinuxHost::InvokeMethodOnMainThread方法向LinuxHost事件隊列注冊事件。

這個過程如下圖所示:

 

 

點擊查看大圖

5.5 訪問Titanium對象屬性和方法

比如,有一段Javascript腳本中調用Titanium.API獲取Titanium對象的API屬性,當JavascriptCore解析到這部分代碼時,并不知道這個對象是什么類型的,完全當作一個抽象的JSValue對象來對待,因為對于Javascript引擎來說,并不需要時刻知道對象是什么,有那些屬性和方法,只有到運行時才會去用查詢該對象中是否存在指定的屬性或者方法(JavascriptCore內部維護了一張屬性表,通過查詢方式獲取相應屬性或者函數的處理函數指針。這點V8做的就比較高明,用類的方式描述,動態將對應JS的方法和屬性轉換成C++的成員函數和成員變量,大量的減少了訪問時間)。由于API這個對象是由Kroll創建的,是一個KObject對象,在掛載到Javascript 全局屬性表之前,Titanium會調用KObjectToJSValue方法,將KObject對象轉換成一個JS的Object對象,并且設置了幾個比較重要的回調函數:

  • HasPropertyCallback: 當查詢屬性時候被調用
  • GetPropertyCallback: 當獲取指定屬性時被調用
  • SetPropertyCallback: 當設置指定屬性時被調用

當javascript訪問用Titanium對象的API屬性時,通過JSValue.Get方法會調用到GetPropertyCallback函數,該函數會查詢KObject對象中(這里是說的Titanium)是否有API這個屬性,如果有則轉換成JSValue對象,并且返回給Javascript引擎。

如果這里訪問的是一個屬性的方法,過程和訪問對象是一樣的,只不過***創建的是一個Function Js對象,而非Object對象。當Javascript訪問這個返回的Function對象時,Javascript引擎會調用callAsFunction方法,而該方法會引發CallAsFunctionCallback回調函數被調用(該函數是靜態函數在KMethodToJSValue函數中注冊)。這樣通過CallAsFunctionCallback這個回調接口,調用實際的KObject的Call方法,執行實際的處理函數。

屬性訪問過程如下圖所示:

 

 

點擊查看大圖

5.6 Javascript、Python、Ruby動態語言間的相互調用

Titanium框架中引入了一個比較有意思的特性,即支持多種語言之間的相互調用。從實現技術角度來說,Titanium的多語言支持的設計思想,是在學習了WebKit的Binding機制而發展過來的。主要用到了JavascriptCore引擎可以動態注冊Evaluator的機制。HTML語言中定義了<script>標簽,用于內嵌腳本語言,該標簽有個子屬性type,通過該屬性可以讓瀏覽器引擎區分是什么類型的腳本。加入我們有如下的腳本代碼:

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

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

這里以Javascript調用Python代碼,并且Python代碼中又調用了ruby代碼為例子說明其調用過程。

Python代碼:

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

Ruby代碼:

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

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

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

整個過程如下圖所示:

 

 

點擊查看大圖

六、參考資源

http://www.appcelerator.com/

責任編輯:佚名 來源: 姜江的博客
相關推薦

2012-04-19 17:16:32

Titanium實例代碼分析

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單元測試

2012-06-14 09:42:20

跨平臺工具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-18 10:08:56

TitaniumAndroid

2012-05-23 09:28:14

Titanium錯誤應對辦法

2012-04-19 11:40:21

Titanium

2012-04-19 16:41:24

Titanium視頻實現頁面跳轉

2012-05-23 09:33:37

TitaniumStudioAndroid APK

2012-05-23 09:46:15

Titanium MoTitanium

2012-05-18 11:16:42

@Kroll注解詳解TitaniumAndroid模塊
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩成人免费av | 国产精品日本一区二区不卡视频 | 国产视频精品视频 | 欧美一级片在线观看 | 久久精品久久精品 | 国产视频一区二区在线观看 | 日日日操 | av中文在线观看 | 久久久久久国产精品久久 | 成人免费视频播放 | 久久精品视频在线免费观看 | 欧美成人精品一区 | 日韩在线看片 | 粉嫩粉嫩芽的虎白女18在线视频 | 97国产一区二区精品久久呦 | 亚洲av毛片成人精品 | 久久成人激情 | 91视视频在线观看入口直接观看 | 91精品国产乱码久久久久久 | 一级a爱片久久毛片 | 97国产精品视频人人做人人爱 | 日日操av | 国产成人免费视频 | 亚洲午夜在线 | 亚洲精品久久久久中文字幕欢迎你 | 九九伊人sl水蜜桃色推荐 | 激情欧美一区二区三区中文字幕 | 欧美精品乱码99久久影院 | 国产资源在线播放 | 欧美aaaaaaaaaa | 91久久精品日日躁夜夜躁欧美 | 欧美a在线看 | 亚洲视频一区在线播放 | 精品一区二区三区不卡 | 日韩中文字幕 | 欧美在线a| 国产精品色哟哟网站 | 一区二区三区视频 | 伊人网站在线 | 国产成人精品一区二区三区 | 中文字幕 在线观看 |