另辟蹊徑創(chuàng)建移動(dòng)應(yīng)用:iOS和Android代碼共享
過去幾年,移動(dòng)應(yīng)用席卷了整個(gè)世界,在工作和生活的方方面面改變著我們使用互聯(lián)網(wǎng)的方式。創(chuàng)建移動(dòng)應(yīng)用的各種技術(shù)也隨之興起,各種開發(fā)流程也 將移動(dòng)應(yīng)用視為一等公民,開始考慮適應(yīng)移動(dòng)開發(fā)的流程。盡管已經(jīng)讓人感覺無處不在,真正的移動(dòng)應(yīng)用時(shí)代才剛剛開始。我們即將面對(duì)新一代的移動(dòng)設(shè)備,如可穿戴設(shè)備或組成物聯(lián)網(wǎng)的各種各樣的移動(dòng)裝置。我們將面臨全新的用于數(shù)據(jù)展示和命令接收的用戶交互接口。我們也認(rèn)識(shí)到越來越多的公司將真正采取移動(dòng)優(yōu)先的戰(zhàn) 略。所有的這些都將對(duì)我們未來幾年設(shè)計(jì)、開發(fā)和測(cè)試軟件的方式產(chǎn)生巨大影響。
在蘋果和安卓的應(yīng)用商店中有成千上萬各種用途的移動(dòng)應(yīng)用。iOS設(shè)備上的應(yīng)用通常使用Objective-C工具庫創(chuàng)建而成,而安卓設(shè)備上的應(yīng)用則 基于Java語言。在這篇文章中我們將向您展示兩種不太常用的使用Java和Xtend構(gòu)建原生應(yīng)用的方法,這兩種方法能夠幫助開發(fā)者在兩個(gè)應(yīng)用平臺(tái)上共享代碼,從而簡(jiǎn)化開發(fā)工作。
使用Java和RoboVM開發(fā)原生iOS應(yīng)用
將安卓和iOS兩個(gè)平臺(tái)同時(shí)作為目標(biāo)平臺(tái)的移動(dòng)應(yīng)用開發(fā)者經(jīng)常面臨很多挑戰(zhàn)。在比較這兩個(gè)平臺(tái)的原生應(yīng)用開發(fā)環(huán)境時(shí),例如分別由谷歌和蘋果提供的開 發(fā)工具鏈,很容易就能夠發(fā)現(xiàn)這兩者之間有著本質(zhì)的區(qū)別。谷歌所提供的安卓開發(fā)環(huán)境是基于Eclipse集成開發(fā)環(huán)境和Java程序設(shè)計(jì)語言的。而由蘋果所 提供的iOS開發(fā)環(huán)境則是基于Xcode集成開發(fā)環(huán)境和Objective-C程序設(shè)計(jì)語言的。
這些平臺(tái)間的差異導(dǎo)致代碼無法重用。而且很少有開發(fā)者能夠同時(shí)精通兩個(gè)環(huán)境。最終就導(dǎo)致幾乎每個(gè)跨平臺(tái)的移動(dòng)應(yīng)用都需要為各個(gè)平臺(tái)準(zhǔn)備單獨(dú)的開發(fā)團(tuán)隊(duì)并使用單獨(dú)的代碼庫。
RoboVM是一個(gè)新的開源項(xiàng)目,旨在不影響開發(fā)者和應(yīng)用用戶體驗(yàn)的前提下解決上述問題。RoboVM項(xiàng)目的目標(biāo)是在iOS設(shè)備上使用Java和其 他JVM語言,如Scala,Clojure和Kotlin。與其他類似的工具不同,RoboVM不會(huì)對(duì)開發(fā)者所使用的Java平臺(tái)特性做任何限制,如反 射機(jī)制或文件I/O,并且還允許開發(fā)人員重用Java龐大的第三方庫生態(tài)系統(tǒng)。RoboVM的獨(dú)特之處還在于開發(fā)人員能夠通過一個(gè)Java到 Objective-C的橋接器訪問到完整的原生iOS API。這樣,應(yīng)用程序開發(fā)時(shí),就能夠用Java語言編寫真正的原生用戶交互界面并且能夠獲取到完整的硬件訪問權(quán)限,同時(shí)使用的開發(fā)工具也是Java開發(fā) 人員所熟悉的Eclipse和Maven等。
使用RoboVM,進(jìn)行跨平臺(tái)開發(fā)將變得相對(duì)容易;同一組Java開發(fā)人員就有能力構(gòu)建兩個(gè)版本的移動(dòng)應(yīng)用程序并且代碼庫中的相當(dāng)一部分代碼都能夠被共享。
如何開始?
RoboVM有多種調(diào)用方式,如命令行方式或使用Maven或Gradle,最容易上手的方式應(yīng)該是使用RoboVM的Eclipse插件。
配置要求
安裝RoboVM的Eclipse插件之前,請(qǐng)確保系統(tǒng)滿足如下要求:
- 一臺(tái)運(yùn)行Mac OS X 10.9操作系統(tǒng)的Mac電腦。
- Oracle Java SE 7 JDK。
- 從Mac應(yīng)用商店下載的Xcode 5.x集成開發(fā)環(huán)境。
需要注意的是,必須使用Oracle Java SE 7 JDK運(yùn)行Eclipse。Eclipse無法正常運(yùn)行在蘋果的Java 6 JVM之上。
安裝RoboVM的Eclipse插件
系統(tǒng)滿足所有的先決條件之后,安裝插件是一項(xiàng)很簡(jiǎn)單的工作。從Eclipse的Help菜單中打開Eclipse Marketplace,搜索RoboVM并點(diǎn)擊Install Now即可。
或者也可以使用如下更新站點(diǎn)。
運(yùn)行一個(gè)簡(jiǎn)單的iOS應(yīng)用
接下來我們將創(chuàng)建一個(gè)簡(jiǎn)單的iOS應(yīng)用。首先創(chuàng)建一個(gè)新的項(xiàng)目:File => New => Project......。在列表中選擇RoboVM iOS Project向?qū)А?/p>
在Project Name,Main Class和App name欄中輸入IOSDemo,在App id一欄中輸入org.robovm.IOSDemo。其他欄目保持默認(rèn)值點(diǎn)擊Finish。
然后,創(chuàng)建一個(gè)新的名為IOSDemo的類文件,省略包名。將下面的代碼拷貝粘貼到新創(chuàng)建的文件中,替換Eclipse自動(dòng)生成的代碼。
- import org.robovm.apple.coregraphics.*;
- import org.robovm.apple.foundation.*;
- import org.robovm.apple.uikit.*;
- public class IOSDemo extends UIApplicationDelegateAdapter {
- private UIWindow window = null;
- private int clickCount = 0;
- @Override
- public boolean didFinishLaunching(UIApplication application,
- NSDictionary launchOptions) {
- final UIButton button = UIButton.create(UIButtonType.RoundedRect);
- button.setFrame(new CGRect(115.0f, 121.0f, 91.0f, 37.0f));
- button.setTitle("Click me!", UIControlState.Normal);
- button.addOnTouchUpInsideListener(new UIControl.OnTouchUpInsideListener() {
- @Override
- public void onTouchUpInside(UIControl control, UIEvent event) {
- button.setTitle("Click #" + (++clickCount), UIControlState.Normal);
- }
- });
- window = new UIWindow(UIScreen.getMainScreen().getBounds());
- window.setBackgroundColor(UIColor.colorLightGray());
- window.addSubview(button);
- window.makeKeyAndVisible();
- return true;
- }
- public static void main(String[] args) {
- NSAutoreleasePool pool = new NSAutoreleasePool();
- UIApplication.main(args, null, IOSDemo.class);
- pool.close();
- }
- }
***,右鍵點(diǎn)擊剛剛創(chuàng)建的項(xiàng)目,選擇Run As... =>iOS Simulator App (iPhone),在iOS模擬器中啟動(dòng)應(yīng)用程序。這樣,應(yīng)用程序就運(yùn)行在一個(gè)模擬的iPhone上了。
如果需要在真實(shí)的設(shè)備上運(yùn)行應(yīng)用程序,需要使用Run As... =>iOS Device App選項(xiàng)。需要注意的是,執(zhí)行這一選項(xiàng)之前,所用到的設(shè)備需要進(jìn)行相應(yīng)的設(shè)置。設(shè)置的過程超出了本文的討論范圍。詳細(xì)信息請(qǐng)參照蘋果的官方文檔。
#p#
創(chuàng)建用于應(yīng)用商店發(fā)布的IPA文件
如果應(yīng)用商店的發(fā)布證書(Distribution Certificate)和應(yīng)用描述文件(Provisioning Profile)已經(jīng)準(zhǔn)備妥當(dāng),創(chuàng)建用于提交到應(yīng)用商店的IPA軟件包只需要在Eclipse中右鍵點(diǎn)擊RoboVM iOS項(xiàng)目,選擇RoboVM Tools=>Package for App Store/Ad-Hoc distribution… ,填寫對(duì)話框中相關(guān)信息即可。
完成上述操作后,將會(huì)在目標(biāo)文件夾中生成一個(gè)后綴為.IPA的文件。使用Application Loader即可驗(yàn)證生成的IPA文件并將其提交到應(yīng)用商店中。使用Spotlight可以很方便地定位到Application Loader應(yīng)用。
從蘋果網(wǎng)站上能夠找到很多關(guān)于如何加入iOS開發(fā)者計(jì)劃及如何創(chuàng)建用于應(yīng)用商店發(fā)布的證書和應(yīng)用描述文件的資源。
底層實(shí)現(xiàn)機(jī)制
字節(jié)碼編譯器
RoboVM的核心是它的預(yù)編譯器。預(yù)編譯器可以通過命令行或者M(jìn)aven、Gradle等構(gòu)建工具或IDE調(diào)用。它可以將Java字節(jié)碼翻譯成用 于特定操作系統(tǒng)和CPU型號(hào)的機(jī)器碼。一般來說會(huì)翻譯成用于iOS系統(tǒng)和ARM處理器的機(jī)器碼,不過RoboVM也支持將字節(jié)碼轉(zhuǎn)為運(yùn)行在x86 CPU(32位)上的Mac OS X和Linux系統(tǒng)的機(jī)器碼。
這種預(yù)編譯的方法與Oracle Hotspot之類的傳統(tǒng)JVM的工作機(jī)制有很大的區(qū)別。這些JVM通常會(huì)在運(yùn)行時(shí)讀取Java字節(jié)碼,然后以某種方式執(zhí)行包含在字節(jié)碼的虛擬機(jī)指令。為 了加快這一進(jìn)程,JVM采用了一種被稱為即時(shí)編譯的技術(shù)。簡(jiǎn)單來說,這個(gè)過程會(huì)在程序***次調(diào)用某個(gè)方法時(shí),將這一方法的虛擬機(jī)指令翻譯成當(dāng)前系統(tǒng)所用的 CPU型號(hào)對(duì)應(yīng)的機(jī)器碼。
由于蘋果內(nèi)置于iOS中的技術(shù)限制,在iOS應(yīng)用中使用任何形式的即時(shí)編譯技術(shù)都是不可能的。唯一的替代方案就是使用解釋器或像RoboVM中所用 的預(yù)編譯技術(shù),而解釋器這種方式速度很慢并且十分耗電。預(yù)編譯的過程發(fā)生在使用開發(fā)者的機(jī)器進(jìn)行編譯的時(shí)候,在iOS設(shè)備上運(yùn)行時(shí),生成的機(jī)器碼就能夠全 速運(yùn)行,因此在速度上可以與由Objective-C編譯生成的代碼媲美,甚至可能會(huì)更快一些。
由于RoboVM預(yù)編譯器消費(fèi)Java字節(jié)碼,而不是Java源代碼,因此至少在理論上可以用于任何能夠編譯成字節(jié)碼的JVM語言。目前已知的 RoboVM預(yù)編譯器能夠正常工作的JVM語言有Scala,Clojure和Kotlin。這種方法的另一個(gè)好處是,可在無需任何原始源代碼的情況下, 在標(biāo)準(zhǔn)JAR文件中的第三方庫上使用RoboVM,這樣就可以在應(yīng)用中使用專有的和閉源的庫。
增量編譯
即使是非常簡(jiǎn)單的RoboVM應(yīng)用,例如IOSDemo應(yīng)用,在***次啟動(dòng)時(shí),都需要耗費(fèi)較長一段時(shí)間。RoboVM編譯器編譯應(yīng)用的過程是從應(yīng)用 的main類開始。然后編譯main類所用到的所有的類,之后再編譯前面的類所用到的所有類,如此循環(huán),直到應(yīng)用所需的所有類均完成編譯為止。在這一過程 中,標(biāo)準(zhǔn)的運(yùn)行時(shí)類,如java.lang.Object和java.lang.String,也包含在編譯的范圍內(nèi)。這是一個(gè)一次性的過程。 RoboVM會(huì)緩存已經(jīng)編譯過的類,只有一個(gè)類或與它有直接依賴關(guān)系的類已經(jīng)發(fā)生了改變時(shí),才會(huì)重新編譯這個(gè)類。
增量編譯和緩存目標(biāo)文件的好處在于能夠減少編譯所耗費(fèi)的時(shí)間。在生成的可執(zhí)行文件中僅包含能夠從Main類觸及到的類可以降低可執(zhí)行文件的大小。不 過,在某些情況下(如通過反射機(jī)制加載類時(shí)),RoboVM編譯器無法決定是否應(yīng)該對(duì)某個(gè)類進(jìn)行編譯。不過,可以給編譯器下達(dá)指令,顯式地將某個(gè)特定的類 或者所有符合某個(gè)條件的類包含在編譯范圍內(nèi)。
基于安卓的運(yùn)行時(shí)類庫
任何的JVM虛擬機(jī)都需要運(yùn)行時(shí)類庫。這個(gè)類庫為所有的Java程序提供標(biāo)準(zhǔn)的包和類,如java.lang.Object和 java.lang.String。RoboVM的運(yùn)行時(shí)類庫來自于安卓開源項(xiàng)目和已經(jīng)被移植到RoboVM的非安卓專用的包中。這就意味著如果Java 或JVM代碼中只用到了安卓標(biāo)準(zhǔn)包中的類,那么這些代碼直接就能夠在RoboVM上正常運(yùn)行。
RoboVM現(xiàn)狀
RoboVM目前仍在開發(fā)過程中,不過已經(jīng)可以基本使用。1.0版本預(yù)計(jì)將在2014年年底之前發(fā)布。
在蘋果應(yīng)用商店中已經(jīng)有至少50個(gè)基于RoboVM的應(yīng)用。已知應(yīng)用程序的***列表請(qǐng)參見這里。
目前為止,大概有50%左右的iOS API可用在基于RoboVM的iOS應(yīng)用中。在RoboVM的Wiki上可以查看到關(guān)于這些綁定的當(dāng)前狀態(tài)列表。截至現(xiàn)在,RoboVM上已經(jīng)能夠運(yùn)行由Scala,Clojure和Kotlin所編寫的代碼。
關(guān)于RoboVM的文檔,目前仍在完善過程中。在2014年晚些時(shí)候,1.0版本發(fā)布時(shí),將會(huì)有較為完備的文檔說明。
RoboVM的應(yīng)用目前仍無法進(jìn)行Debug。這一問題也將在今年的晚些時(shí)候解決。
限制
RoboVM只能夠?qū)⒁呀?jīng)完成預(yù)編譯的類加載到應(yīng)用中。這就意味著在RoboVM應(yīng)用中,無法在運(yùn)行時(shí)使用自定義的類加載器動(dòng)態(tài)創(chuàng)建字節(jié)碼并將其加載到應(yīng)用中。也就是說,RoboVM無法支持運(yùn)行時(shí)創(chuàng)建或修改類的技術(shù)。
更多相關(guān)信息
- 關(guān)于RoboVM項(xiàng)目的更多信息請(qǐng)參考RoboVM網(wǎng)站。
- 可以從GitHub上下載到RoboVM源碼
- 關(guān)于如何配置測(cè)試設(shè)備請(qǐng)參考蘋果的文檔“配置用于開發(fā)的iOS設(shè)備”。
- 關(guān)于如何提交應(yīng)用到應(yīng)用商店,請(qǐng)參考蘋果的應(yīng)用發(fā)布指南。
使用Xtend創(chuàng)建安卓應(yīng)用
Xtend簡(jiǎn)介
Xtend 1是一種可以編譯成可讀Java源碼的靜態(tài)類型程序設(shè)計(jì)語言。這種語言本身是同類設(shè)計(jì)中的***典范,特別是在可 讀性和強(qiáng)大的可擴(kuò)展性方面,不過它也讓Java的互操作性問題顯而易見。這種語言鼓吹函數(shù)式編程風(fēng)格和多分派、擴(kuò)展方法、拉姆達(dá)表達(dá)式及編譯期宏等特性。 與其他的Java替代品不同,Xtend本身并不包含龐大的標(biāo)準(zhǔn)庫,而只是在標(biāo)準(zhǔn)的JDK上添加了一些擴(kuò)展方法。Xtend還可以保證避免Java互操作 性問題的出現(xiàn)并且能夠提供強(qiáng)大的IDE支持。
為什么安卓上的Java如此難用
Java代碼往往十分冗長,特別是在安卓操作系統(tǒng)上。由于Android API的級(jí)別很低而且經(jīng)常出現(xiàn)沒有經(jīng)過充分定義的類型(到處都是int類型)。另外一個(gè)煩惱就是無處不在的XML文件的使用和綁定。由于Android上 尚未支持Java 8,我們還不得不仔細(xì)閱讀無處不在的匿名類。而且不幸的是,Java無法修剪代碼以增強(qiáng)可讀性,我們只能將代碼與多余的符號(hào)、類型信息和樣板習(xí)語 (boilerplate idioms)混雜在一起。
安卓對(duì)JVM語言的***要求
Java語言在安卓上的替代品必須要能夠保證不增加任何運(yùn)行時(shí)的系統(tǒng)開銷,這就將所有的動(dòng)態(tài)語言排除在外。另外,也不希望出現(xiàn)任何不必要的間接類型 轉(zhuǎn)換。例如,代碼中應(yīng)該只使用Java和安卓類型,不應(yīng)因?yàn)榛ゲ僮餍詥栴}而需要來回轉(zhuǎn)換。這不僅是處于性能方面的擔(dān)心,在調(diào)試時(shí)也比較令人煩惱。***,安 卓系統(tǒng)限制每個(gè)應(yīng)用只能夠使用65536個(gè)方法。因此,尋找Java的替代品時(shí),一定不能在應(yīng)用中添加大的標(biāo)準(zhǔn)SDK,因?yàn)檫@樣會(huì)大大減少開發(fā)人員所能使 用的方法數(shù)量。舉例來說,使用Groovy的SDK會(huì)增加8000多個(gè)方法。
Xtend——安卓開發(fā)的***解決方案?
Xtend能夠轉(zhuǎn)化成地道的Java源代碼,并且基本上只依賴于JDK和安卓系統(tǒng)的類。在運(yùn)行時(shí),也沒有間接尋址、轉(zhuǎn)換或者其他任何額外的開銷。也 就是說,Xtend代碼能夠和Java的源代碼有著基本一致的運(yùn)行速度。另外,Xtend還包含一個(gè)經(jīng)過精簡(jiǎn)的為安卓系統(tǒng)提供的運(yùn)行時(shí)庫,只有275kb 大小并且?guī)缀醢四闼枰囊磺?。Xtend Eclipse插件與ADT(安卓開發(fā)工具)的整合也相當(dāng)***,對(duì)于新的安卓構(gòu)建系統(tǒng)3,甚至還提供了相應(yīng)的Gradle插件2。接下來就讓我們?cè)敿?xì)了解一下如何使用Xtend改善典型的安卓代碼。
Hello安卓!
與往常一樣,我們先看一個(gè)簡(jiǎn)單的Hello World示例程序:
- class HelloWorldActivity extends Activity {
- override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState)
- val button = new Button(this)
- button.text = "Say Hello!"
- button.onClickListener = [
- Toast.makeText(context, "Hello Android from Xtend!", Toast.LENGTH_LONG).show
- ]
- val layout = new LinearLayout(this)
- layout.gravity = Gravity.CENTER
- layout.addView(button)
- contentView = layout
- }
- }
對(duì)于Java開發(fā)者來說,這個(gè)例子使用了類Java的編程風(fēng)格,因此***眼看上去會(huì)非常熟悉。另外,你可能會(huì)注意到,示例中所用的API 100%來自于安卓SDK和JDK。
主要的區(qū)別在于:
- 沒有分號(hào)(分號(hào)是可選的)
- 使用setter和getter訪問對(duì)象屬性
- 屬性的默認(rèn)可見性(如,類默認(rèn)是共有的)
- 使用拉姆達(dá)表達(dá)式替代匿名類
在語言的特性方面,有很多地方可以深入探討,不過在此之前,先讓我們看一下如何將Xtend編譯器與相應(yīng)的Android構(gòu)建過程整合在一起。
#p#
使用Gradle進(jìn)行構(gòu)建
對(duì)于目前最常用的三個(gè)構(gòu)建系統(tǒng):Maven,Gradle和Ant,Xtend都有相應(yīng)的插件支持。谷歌最近為安卓項(xiàng)目引入了新的基于Gradle的構(gòu)建系統(tǒng)。接下來我們看一下使用Gradle構(gòu)建我們的“Hello World”項(xiàng)目需要做哪些工作。
本文假設(shè)你已經(jīng)在系統(tǒng)中安裝了***版本的Gradle和安卓SDK并且正確的設(shè)置了ANDROID_HOME環(huán)境變量。同時(shí),你已經(jīng)將Gradle的/bin目錄添加到了PATH環(huán)境變量中。
接下來需要將構(gòu)建腳本“build.gradle”添加到你的Eclipse Android項(xiàng)目的根目錄下,build.gradle文件樣例如下:
- buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:0.8.+'
- classpath 'org.xtend:xtend-gradle-plugin:0.1.+'
- }
- }
- apply plugin: 'android'
- apply plugin: 'xtend-android'
- repositories {
- mavenCentral()
- }
- dependencies {
- compile ('org.eclipse.xtend:org.eclipse.xtend.lib:2.6.+')
- }
- android {
- compileSdkVersion 19
- buildToolsVersion "19.1.0"
- sourceSets {
- main {
- manifest {
- srcFile 'AndroidManifest.xml'
- }
- java {
- srcDir 'src'
- }
- res {
- srcDir 'res'
- }
- assets {
- srcDir 'assets'
- }
- resources {
- srcDir 'src'
- }
- aidl {
- srcDir 'src'
- }
- }
- }
- }
其主要工作就是導(dǎo)入并調(diào)用Maven和Xtend的構(gòu)建插件。此外,我們將運(yùn)行時(shí)庫添加到項(xiàng)目中并告知Android插件我們正在使用 Eclipse風(fēng)格的項(xiàng)目布局。上述工作完成后,在命令行窗口中進(jìn)入項(xiàng)目的根目錄并運(yùn)行“gradle build”,Gradle將為你完成剩余的所有工作。
深入Xtend
除了語法糖之外,Xtend還附帶了許多非常有用的語言特性,例如操作符重載,模板表達(dá)式和switch表達(dá)式。而且還可以通過結(jié)合不同的功能創(chuàng)建 新的特性。例如,假如你需要?jiǎng)討B(tài)的UI,不能用靜態(tài)的XML文件構(gòu)建,而需要聲明式的編寫。Xtend為開發(fā)者提供了構(gòu)建器語法(builder syntax)的支持。“Hello World”實(shí)例的UI實(shí)現(xiàn)代碼如下:
- import static extension com.example.helloworld.UiBuilder.*
- class HelloWorldActivity extends Activity {
- override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState)
- contentView = linearLayout [
- gravity = Gravity.CENTER
- addButton("Say Hello!") [
- onClickListener = [
- Toast.makeText(context,
- "Hello Android from Xtend!",
- Toast.LENGTH_LONG).show
- ]
- ]
- ]
- }
- }
linearLayout(Context ctx, (LinearLayout)=>void initializer) 和button(ViewGroup group, String name, (Button)=>void initializer) 兩個(gè)方法作為擴(kuò)展被引入到Activity中。這兩個(gè)方法將拉姆達(dá)函數(shù)作為其參數(shù)之一。傳入拉姆達(dá)函數(shù)中的參數(shù)被稱為implicit it,與this類似,implicit it不需要顯式地解引用。如上所示,拉姆達(dá)函數(shù),擴(kuò)展方法和implicit it結(jié)合使用能夠產(chǎn)生非常漂亮的構(gòu)建器語法。通過Xtend也可以構(gòu)建許多其他漂亮的API,從而以一種易讀的聲明式的方式編寫代碼。
來自于XML地獄的問候!
安卓開發(fā)者的相當(dāng)一大部分日常工作就是配置和開發(fā)各種XML文件,用作國際化字符串的資源或用于各類視圖的聲明。安卓平臺(tái)推薦使用XML文件,因?yàn)?平臺(tái)已經(jīng)為開發(fā)者提供了針對(duì)大型設(shè)備和SDK碎片化的解決方案。然而應(yīng)用程序最終不可能只由靜態(tài)視圖和數(shù)據(jù)組成。開發(fā)者需要將所有的素材組合并為其賦予生 命。在安卓平臺(tái),通過R類來完成這些工作。這個(gè)自動(dòng)生成的類包含了許多對(duì)應(yīng)在XML文件中聲明的各種元素的整型常量。假設(shè)一個(gè)視圖XML文件中聲明了如下 兩個(gè)元素,點(diǎn)擊Button可以更新TextView中的消息:
- <TextView android:id="@+id/message_view"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:hint="@string/empty" >
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:onClick="sayHello"
- android:text="@string/hello_world" >
- </Button>
典型的安卓式開發(fā)方法是通過R類中生成的常量獲取到TextView的控制權(quán)然后實(shí)現(xiàn)onClick的回調(diào)方法“sayHello”:
- class HelloWorldActivity extends Activity {
- TextView messageView
- override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState)
- // set the view using the int constant
- contentView = R.layout.main
- // get a handle on the TextView
- messageView = findViewById(R.id.message_view) as TextView
- }
- /**
- * Callback automagically called by Android
- */
- def void sayHello(View v) {
- messageView.text = "Hello Android from Xtend!"
- }
- }
上面一段安卓的典型代碼中包含了不安全的類型轉(zhuǎn)換,命名規(guī)范和各種樣板文件。用Xtend我們能夠做得更好。
你好,Xtendroid!
Xtendroid4是一個(gè)專門為安卓開發(fā)提供類庫以及所謂的積極注解(active annotation)的小型項(xiàng)目。積極注解可以理解為編譯時(shí)的宏,它能夠參與到從Xtend到Java轉(zhuǎn)化的編譯過程中。你可以隨意修改被注解的類,生成附加類型或使用這個(gè)鉤子讀寫純文本文件。
這樣只要有一個(gè)注釋,我們就知道要綁定哪個(gè)視圖并且注釋還可以幫助我們生成樣板文件。除此之外,它還能夠提供類型安全的元素訪問方法和回調(diào)方法。下面一段代碼就是用Xtendroid的@AndroidActivity注釋編寫的Activity類。
- @AndroidActivity(R.layout.main) class HelloWorldActivity {
- /**
- * Type safe callback
- */
- override void sayHello(View v) {
- messageView.text = "Hello Android from Xtend!"
- }
- }
現(xiàn)在,這個(gè)Activity中只包含了我們想要加入的行為。其他的設(shè)置都是自動(dòng)實(shí)現(xiàn)的,例如設(shè)置管道綁定、內(nèi)容視圖或擴(kuò)展Activity的樣板文件。而且現(xiàn)在一切都是類型安全的,IDE能夠了解其中的來龍去脈并為開發(fā)者提供適當(dāng)?shù)淖詣?dòng)完成建議。
此外,Xtendroid還能夠?yàn)殚_發(fā)者處理JSON對(duì)象,資源文件或SQLite數(shù)據(jù)庫提供便利。而且,積極注解以庫的形式存在,因此通過自行開發(fā)或定制化已有庫的方式,開發(fā)者可以很容易地構(gòu)建更適于自己的庫。
從下方1下載Eclipse并使用更新站點(diǎn)5安裝ADT就可以開始自己親自嘗試上面所講的內(nèi)容。Xtendroid項(xiàng)目包含許多類似本文中所展示的示例。***祝大家能從中找到樂趣。
關(guān)于作者
Niklas Therning是開源項(xiàng)目RoboVM的創(chuàng)建者和的聯(lián)合創(chuàng)始人——RoboVM項(xiàng)目的主要貢獻(xiàn)者。他把如何合理地將Java引入iOS平臺(tái)作為其使命。開始RoboVM項(xiàng) 目前,Niklas參與創(chuàng)建了SpamDrain反垃圾郵件服務(wù),并且作為其承包商,主要從事Java EE和web應(yīng)用程序開發(fā)的工作。Niklas持有位瑞典哥德堡查爾姆斯理工大學(xué)的計(jì)算機(jī)科學(xué)理學(xué)碩士學(xué)位??梢酝ㄟ^Twitter賬號(hào)@robovm關(guān)注他。
Sven Efftinge是一個(gè)充滿激情的軟件開發(fā)人員,他喜歡風(fēng)箏沖浪運(yùn)動(dòng)、音樂和美食。他是Xtext項(xiàng)目的領(lǐng)導(dǎo)人。Xtext是一個(gè)程序設(shè)計(jì)語言、領(lǐng)域特定語言和JVM靜態(tài)類型程序設(shè)計(jì)語言Xtend的開發(fā)框架。在位于Kiel的itemis公司,Sven領(lǐng)導(dǎo)一個(gè)研究部門。
過去幾年,移動(dòng)應(yīng)用席卷了整個(gè)世界,在工作和生活的方方面面改變著我們使用互聯(lián)網(wǎng)的方式。創(chuàng)建移動(dòng)應(yīng)用的各種技術(shù)也隨之興起,各種開發(fā)流程也 將移動(dòng)應(yīng)用視為一等公民,開始考慮適應(yīng)移動(dòng)開發(fā)的流程。盡管已經(jīng)讓人感覺無處不在,真正的移動(dòng)應(yīng)用時(shí)代才剛剛開始。我們即將面對(duì)新一代的移動(dòng)設(shè)備,如可穿 戴設(shè)備或組成物聯(lián)網(wǎng)的各種各樣的移動(dòng)裝置。我們將面臨全新的用于數(shù)據(jù)展示和命令接收的用戶交互接口。我們也認(rèn)識(shí)到越來越多的公司將真正采取移動(dòng)優(yōu)先的戰(zhàn) 略。所有的這些都將對(duì)我們未來幾年設(shè)計(jì)、開發(fā)和測(cè)試軟件的方式產(chǎn)生巨大影響。
譯文原文:另辟蹊徑創(chuàng)建移動(dòng)應(yīng)用
查看英文原文:Unusual Ways to Create a Mobile App