在 KDAB ( the Qt experts ) 上看到了 BogDan Vatra 的Qt on Android 的系列文章,生了翻譯的念頭,那就開始吧。
我會跟隨BogDan Vatra 在 KDAB 上的的博客文章進行翻譯,如需轉(zhuǎn)載,請注明譯者 foruok ( 2014-4-14日我正式取得了 BogDan Vatra 和 KDAB 的授權(quán))。
本文的英文鏈接原文: Qt on Android Episode 1 ,作者為 BogDan Vatra。中文譯者 foruok 。轉(zhuǎn)載請注明出處 http://blog.csdn.net/foruok 。
這里先對 BogDan Vatra作個簡單介紹:
BogDan Vatra ,今年 34 歲(和我同歲,哈哈), 居住在羅馬尼亞中部的布拉索夫城。
BogDan Vatra 有 13 年多的 C/C++ 開發(fā)經(jīng)驗,11 年多的 Qt 開發(fā)經(jīng)驗。 BogDan Vatra 主導(dǎo)開發(fā)過多個開源項目,eXaro (exaro.sf.net) , Necessitas , Ministro (Qt on Andriod) 是比較著名且有影響力的三個。
eXaro 是基于 Qt 的、開源的、免費的報表引擎,與 Windows 下的水晶報表類似。
Necessitas 是由 BogDan Vatra 創(chuàng)建的開源項目,是針對 Android 平臺的 Qt 移植版本,在發(fā)布后大獲成功。后來 BogDan Vatra 將其中的一個移植版本貢獻給 Qt Project ,是 Qt 5.2 中 Android 功能的前身。
Ministro 是 BogDan Vatra 為了在同一 Android 設(shè)備上多個使用 Qt 的應(yīng)用之間共享 Qt 庫而設(shè)計的解決方案。
BogDan目前為 KDAB 進行開發(fā)工作。
以下是譯文。
我打算針對Qt on Android 這個主題撰寫一個系列文章。
第一篇文章的內(nèi)容:它(注:指 Qt on Android)如何開始、怎樣工作、當(dāng)前的狀態(tài)、應(yīng)當(dāng)對 Qt 5.2 期望什么以及我對 Qt 5.3 的計劃。下一篇文章我會把重點放在如何搭建安卓開發(fā)環(huán)境上。
我們開始吧。
它(注:指 Qt on Android )到底是怎么開始的呢?
2009年6月,我作為一個資深的 Linux 開發(fā)者加入了 ROUTE 66 。我的第一個任務(wù)是把現(xiàn)有的導(dǎo)航引擎移植到安卓平臺上。那時候 Google 還沒有釋放任何的官方 NDK ,所以我必須自己從 Android 源碼創(chuàng)建一個我自己的 NDK 。
不久以后,我完成了一個可以在 Android 上工作的引擎。我開始喜歡 Android 了,但是我總覺得缺了點東西,而且是我非常關(guān)注在意的東西。——那就是 Qt,我鐘愛的框架。這( Qt )就是缺失的那點東西!我對自己說,我必須為它做點什么。
2009年的10月份, Nokia (嗯,那時候 Qt 歸 Nokia 所有,什么日子啊……)發(fā)布了 Lighthouse 項目。 Lighthouse 項目的創(chuàng)建,是為了讓開發(fā)者們更方便的把 Qt 移植到任意的平臺上。
2009 年 12 月后期(我想是圣誕節(jié)之后),我有足夠的空閑時間可以開始移植工作。我選擇了 Lighthouse 項目,盡管它還是一個非常年輕的研究性項目。據(jù)我所知,我的 Android 移植,是第一個使用 Lighthouse 的移植。僅僅過了一個月( 2010 年 1 月),我在我的手機上看到了 Qt 繪制出來的第一個圖形。那種感覺,實在是好極了。
幾個月后,當(dāng) Qt 達(dá)到一個相對良好的狀態(tài)后,我開始了 Qt Creator 插件和Ministro (注:Ministro 是一個全系統(tǒng)的 Qt 的共享庫安裝程序/服務(wù)提供者的服務(wù))的工作。這個 Qt Creator 插件使得使用者可以非常方便的在安卓設(shè)備或模擬器上管理、開發(fā)、部署、運行、調(diào)試 Qt 應(yīng)用程序。
即使幾乎一切都到位了,還是沒多少人愿意使用,因為他們必須手動編譯所有東西。因此我決定為此做點兒工作。
2011 年,在 Nokia 宣布他們的重大戰(zhàn)略轉(zhuǎn)移的幾個星期之后,我發(fā)布了第一個可用的 Qt Android SDK 。這就是 Necessitas 項目怎么開始的,之后它獲得了巨大的成功,我決定加入 KDE ,在它的佑護下繼續(xù)項目。為什么選擇 KDE ?因為我們擁有同一個目標(biāo):保持 Qt 的強大和對所有人免費。而且我可以使用他們出色的系統(tǒng)來發(fā)布 Qt 庫。
最初釋放的(Qt Android) SDK 只能在 Linux 下使用。很快地,Ray Donnelly 聯(lián)系了我并且把 SDK 移植到了 Windows 和 Mac 上。如果你在這些平臺上使用 Necessitas (和 and Qt5 Android SDK ),你應(yīng)該感謝這個家伙。
和 Ray 及其他人一起,我們完成了Necessitas SDK 的很多很多次發(fā)布。
因為(我們的) Qt Creator 插件非常成功,我在 2012 年提交了這個插件,那時候 Qt 仍然歸 Nokia 所有!
2012 年 11 月,為了 Qt 5 的整合,我向 Qt Project 貢獻了這個安卓移植版本。這里得作個聲明:只有 Qt 5 是在 Qt Project 的佑護下開發(fā)的,Qt 4 仍由 KDE Necessitas 項目所擁有。
讓我們大概地看看 Qt on Android 是如何工作的,我不會去太深入細(xì)節(jié),但足夠讓你了解它是如何工作的。
就像我之前寫的,移植是基于Lighthouse 項目的。Lighthouse (現(xiàn)在更名為 QPA )是 Qt 的一個平臺抽象層。基本上這一層介于 Qt 與平臺之間,簡化了移植工作。因為 Android 應(yīng)用程序使用 Java 語言編寫,不可能直接把 Qt 的事件循環(huán)和 Android 的事件循環(huán)直接連起來,我必須把 Qt 的主事件循環(huán)移動到一個線程中。如果你想擴展你的應(yīng)用程序,必須明白這個事實:Qt 的事件循環(huán)和 Java UI 是運行在不同的線程中。即便在 Google 增加了 NativeActivity 之后,我們也不可能使用它,主要是因為它沒有暴露 Qt 需要的所有特性。
一個 Qt for Android 應(yīng)用程序包含兩個大的部分:
- 原生部分,包含一個或多個動態(tài)庫文件( .so ),實際上就是你的 Qt 應(yīng)用程序。如果你選擇捆綁 Qt 庫,那么也包含所有需要的庫文件。
-
Android 相關(guān)部分,這部分又包含下面幾部分:
- Android manifest ,這是你應(yīng)用程序的入口。 Android 使用這個文件決定啟動哪個應(yīng)用或活動,它描述了應(yīng)用需要的權(quán)限、 Android API 版本等等信息
- 兩個 Java 類,加載依賴項和你的應(yīng)用。它們也是 Qt QPA 和 Android 世界之間的由 Java 實現(xiàn)的橋梁的一部分。
- Ministro service .aidl 文件。這是兩個用于和Ministro service 通信的接口。Ministro service 是部署方案之一,稍后會詳細(xì)的討論。
- 其它的一些資源,如assets, strings, images 等等。
所有這些組成部分被組織在一個包中,這個包代表了你最終的應(yīng)用程序。現(xiàn)在讓我們看看這些部分如何一起工作。
當(dāng)你的應(yīng)用程序啟動時, Android 使用 manifest 文件啟動一個活動( Activity )。這個活動是你應(yīng)用程序中 Java 世界魔法的一小部分。為了在不中斷現(xiàn)有應(yīng)用的前提下更新 Qt 庫, Java 部分被分割為兩塊:一部分?jǐn)y帶你的應(yīng)用程序(的一部分),另外一部分(一個 Java 庫,一個 .jar 文件)包含了 QPA 插件的所有邏輯。
攜帶你的應(yīng)用程序的第一個 Java 部分負(fù)責(zé)尋找依賴(注:原文為 missing ,但我覺得翻譯為依賴更好些)的庫( Qt 和 Java )并加載他們。同時它也轉(zhuǎn)發(fā)所有的事件(觸摸、應(yīng)用程序狀態(tài)變更、屏幕變化等)給第二個 Java 部分。
第二個 Java 部分負(fù)責(zé)與 Qt 通信。它包括 Android QPA 插件需要的邏輯,例如創(chuàng)建和管理繪圖表面( drawing surface),虛擬鍵盤處理等等。
那么,第一個 Java 部分查找、加載所有依賴的庫和你的應(yīng)用并且轉(zhuǎn)發(fā)所有事件給第二個部分,但你的 main 函數(shù)是怎樣被調(diào)用的呢?好吧,QPA 插件做了這件事兒。不,我沒搞錯! QPA 插件確確實實在你的應(yīng)用啟動之前已經(jīng)加載了(實際上在你的應(yīng)用被加載前它已經(jīng)加載了)。
好吧,讓我來解釋為什么我有這樣一個瘋狂的設(shè)計。
我的夢想是找到一個方法,以便開發(fā)人員可以只編譯他們?yōu)?Android 開發(fā)的 Qt 應(yīng)用,因此我必須找到一個途徑來調(diào)用 main 方法(我不想強制你為你的應(yīng)用創(chuàng)建其它名字的入口函數(shù),比如 WinMain)。
問題是,為了從 Java 中調(diào)用一個 native 方法,你必須先注冊那個方法,否則你就不能調(diào)用它(注:這里指 jni 的調(diào)用方式),在這種情境下, QPA 應(yīng)運而生。 QPA 插件被加載后,它注冊了少數(shù)幾個 native 函數(shù),Java 部分使用這些函數(shù)作為橋梁,進一步地調(diào)用 native 世界中的更多函數(shù)。在 Java 部分加載完所有的庫和你的應(yīng)用之后,它只需要調(diào)用startQtApplication 這個由 QPA 插件在之前注冊過的 native 方法。這個方法搜索方法符號表找到 main 方法后,創(chuàng)建一個線程并在該線程中運行 main 方法。它必須創(chuàng)建一個線程,因為調(diào)用 main 方法會阻塞調(diào)用者直到 main 方法退出,而我們必須保持 Android UI 線程自由(非阻塞)以便運行 Android 事件循環(huán)。
在稍后的一篇文章中,我將介紹如何使用 JNI 在 Java 和 C/C++ 之間進行調(diào)用。
最后,讓我們看看 Qt on Android 的當(dāng)前狀態(tài),你能從 Qt 5.2 得到什么,以及 Qt 5.3 for Android 的計劃。
Qt Essentials status:
Qt Add-Ons status:
感謝您花時間閱讀。
下次再見的時候我們討論怎樣搭建 Qt for Android 開發(fā)環(huán)境。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
