Windows下Scala編程環境的構建:Scala on Android開發


概述


    開發Android應用程序,大家都已知是使用Java編程語言,為何要用Scala?有什么意義?

    學習函數式編程,比Scala編程語言更加“更正苗紅”的函數式編程語言有其它的選擇,為何要選擇Scala編程語言?

    首先,用Scala開發Android app,已經有很多人這樣做了,絕非什么新鮮事;其次,個人非常不喜歡Java編程語言,感覺不自由,抽象層次還是偏低,等等,而Scala語言就沒有Java的那些問題,對於提高產能和效率,應該比Java更好;再次,Android應用程序的開發,實際是在JVM上做開發,JVM Langauge其實有很多,只不過Scala是其中呼聲較高,前途光明的一個。

    Scala實際不僅僅是函數式編程語言,它是一種支持多范型開發的編程語言,同時支持描述式和命令式的編程思想。使用它,首先,有利於對二者的比較,容易理解函數式開發的思想;其次,按照Anders Hejlsberg的說法,多范型和並發的支持是編程語言發展的趨勢,Scala很好的支持了這個說法,所以我選擇了Scala。在學習和掌握了Scala之后,可以進一步的學習那些比較純粹的函數式編程語言,那是后話了。

    那么Scala on Android,可以有2種理解:

    1)開發的是Scala應用程序,Android其實主要是提供一套GUI框架,這樣可以理解成Scala在智能手機領域的的應用。

    2)開發的是Android應用程序,只是把JAVA語言換成另一種效率更高的JVM編程語言Scala,以提高Android app的開發能力和效率。最終還是打包為運行在android機器上的apk。

    本文是按照第二種理解,說明如何使用IntelliJ IDEA Community進行Scala on Android的開發。

基礎


    1,Android的開發環境已經配置好,並正常進行IDEA下Android app的開發。

clipboard

    上圖是相關環境變量的配置。注意ANDROID_HOME和ANDROID_SDK_HOME的區別,后者是用來指明avd創建的路徑的。

    2,Android的項目編譯,是使用Ant管理的,要熟悉Ant的用法。 

    3,除了IDE提供的ant,我們還需要自己在Console下運行ant,還有proguard,所以單獨安裝一份。 

http://proguard.sourceforge.net/ 4.8

http://ant.apache.org/ 1.8.4

    它們沒有MSI安裝文件,解壓縮zip,並配置PATH:

clipboard[1]

clipboard[2]

構建思路


    1,按照對Scala on Android的2種理解,其實有2個方式來構建:

    1)首先創建一個Scala項目,然后使其支持Android的開發。

    2)首先創建一個Android項目,然后使其支持使用Scala語言。

    而且Scala項目和Android項目的創建,又都有2種方式:

    1)使用Console工具

    2)使用IDE

    所以總共就有4種方式來構建Scala on Android。結合前面幾篇文章的說明,可以先確定一點:優先使用IDE。所以結果就變成了2個方式:

    1)用IDEA先創建一個Scala項目,然后使其支持Android。

    2)用IDEA先創建一個Android項目,然后使其支持Scala。

    后文分別說明這2種方式。

    2,參考網上的資料:

    1) http://chneukirchen.org/blog/archive/2009/04/programming-for-android-with-scala.html

    此文比較早,說明了比較早期的做法,也說明了下scala的lib如何轉換成dex格式的。還需要額外拷貝scala的lib到項目的目錄中,然后修改build.xml。

    2) http://lampwww.epfl.ch/~michelou/android/

    這個網站要近一些,這里很有價值,其中不僅有文檔說明,還有把Android sample的代碼轉換成scala的示例代碼,可以幫助大家學習如何進行Scala on Android的實際開發。相比上一個鏈接,這里是完整的解決方案。不過遺憾的是,它並沒有及時更新,最近的也是10個月之前,無法在最新的Android sdk環境下(Android tools r21.1)直接使用。這里的解決方案是針對Scala 2.9.x + Android tools r19的環境,對於最新的Scala 2.10.x以及Android tools r21.1的環境,都沒有說明。

clipboard[3]

    通過這個鏈接,可以得到那些從Android Java code轉換成 Scala code的示例項目的。

    其中,https://github.com/michelou/android-examples/tree/master/hello-android/configs/ant中的build-scala.xml是關鍵,它是本文后續改進的基礎。

    3) http://yinghau76.github.com/2012/12/08/trying-scala-on-android/

    這個鏈接是最近的更新了。在上一個鏈接的基礎上,提供了一個mac-shim.xml,配合build-scala.xml(2個鏈接中是一樣的),可以支持Android tools r21.1。其實這個腳本並不只是如它的網頁上所說,用來解決Linux和MacOS之間的兼容問題, 它實際是解決了Android tools r19中的ant build.xml升級到r21.1后的兼容問題,因為build-scala.xml中使用的一些路徑和變量,是基於r19中的Ant build.xml的,到了r21.1中的Ant build.xml,已經變化,后文會解釋。

    但是,這個鏈接中的內容,還是沒有提供從Scala 2.9.x升級到2.10.x的解決方案,以及如何在IntelliJ IDEA中調試的問題。

    本文就是在這些前輩的基礎上,進一步把Scala on Android的構建腳本,升級到適應最新的Scala和Android開發環境中。下面,以圖文的方式demo下,如何使用IDEA構建、調試一個簡單的Scala On Android的項目。

先Scala,后Android


    1,新建一個Scala項目,命名為 HelloScalaOnAndroid,由於上一篇中設置了Global Libraries,所以這里自動使用Existent Library。

clipboard[4]

    2,打開project structure(別說這個還不知道怎么操作哦,上一篇已經講過了),增加Android facet。這相當於Eclipse中Add xxx nature的功能。

clipboard[5]

clipboard[6]

clipboard[7]

    然后修改Project SDK為Android,這里選擇4.0.3:

clipboard[8]

    檢查下現在project modules:

clipboard[9]

    現在這個Scala項目已經支持2種facets了,已經是一個Android + Scala的混合項目。OK退出。

在IDEA中的這些配置,其實不影響Scala On Android項目的編譯,但涉及在IDEA中的編碼以及調試。編譯是由Ant來負責的,IDEA只是要調用它。

    3,創建AndroidManifes.xml文件,以及Android project所需要的目錄結構和文件,比如res目錄和文件。這一步純手工。

clipboard[10]

clipboard[11]

    4,下面,使用cygwin,在命令行下運行android update project生成Android項目所需的配置文件:

clipboard[12]

    這樣我們得到4支文件,這樣一個Android Project的基本結構就可以了。

    5,創建一個Scala class,表示一個Android activity。按照AndroidManifest.xml中的Package和Activity命名:

clipboard[13]

    並修改代碼如下:

clipboard[14]

    6,下面,創建debug configuration。選擇Android Application類型,命名,選擇Module。注意到默認的Before launch是Make。

clipboard[15]

    到此,從Scala項目開始,建立起來一個Scala on Android項目的基本結構,不過現在build,是肯定會失敗的。(這里涉及IDEA的Make是如何工作的,暫時沒有分析。)

clipboard[16]

    接下去,就是如何把參考鏈接中的解決方案用上了。不過,先看完如何從Android項目入手,構建一個Scala on Android項目。

先Android,后Scala


    1,創建一個Android項目,同樣命名為 HelloScalaOnAndroid。(如果在同一個目錄下,要先刪除上一節創建的同名項目哦)

clipboard[17]

clipboard[18]

    簡單直接,一個完整的Android Project就OK了,比手動調用android update project創建的,還多出了一個ant.properties。還多了一些子目錄:assets, libs。

    2,增加Scala facet。還是通過project structure:

clipboard[19]

    然后:

clipboard[20]

    這里選擇Global libraries中的scala 2.10.0 compiler。然后是:

clipboard[21]

    增加對Scala library的依賴:

clipboard[22]

    OK退出后, IDEA會有一個bubble提示,是關於Scala的"Configure type-aware highlighting for the project"的,推薦Enable它。

clipboard[23]

    4,修改一個地方,這樣后面支持可以安裝到android 2.3.3的 emulator target上,當然也可以不改。

clipboard[24]

    5,因為debug configuration也是自動創建好的,所以只需要把Java Code修改成Scala Code。右擊com.example.HelloScalaOnAndroid,創建一個Scala class,命名為MyActivity,修改內容,然后刪掉同名的MyActivity.java(要把safe delete disable掉)。

clipboard[25]

    至此,從Android項目入手,一個Scala On Android項目同樣准備好了,當然也是不能build的。同樣的錯誤。

小結


     1,無論是從創建Scala項目,還是Android項目入手,最終殊途同歸,一個Scala on Android項目的結構其實是一樣的。

    2,通過比較,還是從Android入手,省事。

    3,在IDEA上選擇的Scala Compiler & Library的版本,其實不影響它的編譯,只是涉及在IDEA中編碼時使用的Scala的語言功能。當然,也應跟編譯系統中的設定一致為好。

    4,這部分只是使用IDEA搭建了一個Scala on Android項目的基礎,不是難點,下面暫時離開IDEA,重點說明下編譯系統的 改進,最后再回到IDEA,看下如何在IDEA中進行debug。

編譯


     1,下面,根據鏈接http://yinghau76.github.com/2012/12/08/trying-scala-on-android/中的內容,獲取一些文件:

    1) mac-shim.xml

    2) build-scala.xml

    3) proguard-template.cfg

 
        

    並且,參考build.xmlant.properties中的寫法。

    2,新建一個config子目錄,將下載的mac-shim.xml、build-scala.xml和proguard-template.cfg放入其中,然后修改build.xml和ant.properties文件,指定Scala和proguard的根目錄。新建一個config子目錄,主要用來統一管理這些腳本。

clipboard[26]

clipboard[27]

    以及,config/build-scala.xml,把94,95行的2處從"basedir"改成"config.dir"。

clipboard[28]

    3,打開cygwin,在項目的根目錄下,試運行:

clipboard[29]

clipboard[30]

clipboard[31]

    Great! 成功了。可見,在最新的Android tools r21.1和Scala 2.9.2的環境下,這些腳本完全可以用。

    4,下面,嘗試運行到emulator上:

clipboard[32]

clipboard[33]

clipboard[34]

    Great! 運行也正常的。

分析


     1,可以嘗試先把config/mac-shim.xml文件移除,再重新ant debug,此時是肯定會出錯的(最好自己做一下,看看是什么錯誤信息)。所以mac-shim.xml中的內容是怎么得來的呢?

    2,在 build-scala.xml的commit message中,得知 updage for r19,其實就是Android tools r19,而現在已經到r21.1了。所以,只要對比下2個版本的 Ant build.xml,就可知了。r19的版本可以從:http://dl-ssl.google.com/android/repository/tools_r19-windows.zip得到。相對路徑在ANDROID_HOME/tools/ant/build.xml。

    經過對比以及移除mac-shim.xml后嘗試build的出錯信息,可知從r19到r21.1:

    1)project.libraries.jars改為project.all.jars.path。

    2)android.target.classpath改為project.target.class.path。

    3)extensible.classpath和extensible.libs.classpath是r21.1中缺少的,需要Porting。

    3,buils-scala.xml還需要一個變量proguard.dir,這個變量可以設置在任何地方:ant.properties、build.xml、build-scala.xml、mac-shim.xml、local.properties、project.properties中。考慮與Scala On Android腳本的關聯性,放在ant.properties,以及build-scala.xml、mac-shim.xml是合適的。本文就是放在ant.properties。

    下面,更換Scala的版本,看看在2.10.x上,有什么表現。

支持Scala 2.10.x


     1,修改ant.properties,設置scala.dir到2.10.1-RC3。(先把Scala 2.10.1-RC3下載好,放在一個目錄下)

clipboard[35]

    2,重新試運行ant:

clipboard[36]

    Oops!Fail~ 這次應該是Scala升版,有了什么變化,導致build-scala.xml不匹配了。經過查找,需要修改build-scala.xml:

clipboard[37]

    再次運行ant:

clipboard[38]

    又出錯了~ 這次是proguard的template腳本有問題。proguard會shrink Scala的libraries,shrink后導致一些符號找不到引用了。再次修改,按照下面的diff,刪除那些相關的內容:

clipboard[39]

    再次run ant,發現還有can't find referenced class sun.misc.Unsafe的錯誤,網上有人認為這是Scala的bug,其實應該是proguard的事情。繼續修改proguard-template.cfg文件,增加這些內容:

clipboard[40]

    這次,終於編譯通過了!

clipboard[41]

    這些對proguard-template.cfg的改動,實際上就是阻止對Scala 2.10.x中的這些class進行obscure和 shrink,以保證找到引用。

    到目前為止,可以支持Scala 2.10.x版本了! 編譯系統全部構建完畢!接下來,回到IDEA,看看如何Debug。

在IDEA中Debug


     上面已經提到,使用IDEA中的Make是無法編譯成功的,更無法進行調試了。上一大節,我們構建好了編譯系統。現在,只要使IDEA調用Ant來進行編譯即可。

    1, IDE最右邊的一列上的“Ant Build”,就是用來設置用Ant管理項目編譯的。現在看起來,內容為空。通過“+”按鈕,把build.xml文件導入,然后就會出現許多build targets了。

clipboard[42]

clipboard[43]

    可見,最下面的2個就是build-scala.xml中增加的目標。黑體是ant的 primary targets,灰色的不是。

    2,重新設置Debug configuration。在Before launch中選擇Run Ant target。

clipboard[44]

    選擇build-scala.xml中的target,-post-compile-scala:

clipboard[45]

    OK后,返回。然后把原來的Make刪除。

clipboard[46]

    OK退出。

    3,下面我們來嘗試運行Debug,現在code里加個斷點。

clipboard[47]

    啟動emulator后,Fail了!

clipboard[48]

    從結果上來看,IDEA需要out\production\HelloScalaOnAndroid\下的一個apk,但實際上Ant是在bin\下生成的apk,所以要么將其copy到out下的指定目錄,要么在IDEA中指明從bin下去拿apk。

    1)解決方法一:打開project structure,在android module下的compiler頁中,設置APK path:

clipboard[49]

    將其設置為bin\HelloScalaOnAndroid-debug.apk。OK退出。

    2)解決方法二:修改Ant腳本,增加一個build target,這里新建一個xml文件,然后在build.xml中導入:

clipboard[50]

    實際上就是把HelloScalaOnAndroid-debug.apk拷貝並重命名為HelloScalaOnAndroid.apk。

clipboard[51]

    然后再次修改下debug configuration,把上面設置的-post-compile-scala改成debug-for-intellij。

clipboard[52]

    4,無論哪種方法,這次重新Debug,終於可以了~

clipboard[53]

clipboard[54]

    至此,使用IDEA構建和調試Scala on Android的開發環境已全部完畢。

總結


     1,相比2種Scala on Android的項目構建方式,從Android項目入手,要比從Scala項目入手要方便、直接一些。

    2,對於前輩們總結出來的解決方案,一定要耐心分析它們在新的版本環境中無法再工作的原因,細致分析之后,總能找到解決方法。

    3,IDEA雖然可以調用Ant腳本,但還是不能直接辨認它的生成路徑,做為一個Android項目,調試時,還是按照默認的APK Path去拿apk。

本文所示代碼倉庫


     1,根據前輩的解決方案,我自己整理的Ant腳本,以及示例項目的代碼,已放到gitcafe和bitbucket中。

    gitcafe:https://gitcafe.com/leo.l.cao/HelloScalaOnAndroid

    bitbucket:https://bitbucket.org/leolcao/helloscalaonandroid

    注意它們都有一個submodule,clone時要帶參數。我修改的那些ant和proguard腳本,放在一個單獨的倉庫中。

    gitcafe:https://gitcafe.com/leo.l.cao/scala-on-android-scripts

    bitbucket:https://bitbucket.org/leolcao/scala-on-android-scripts

    BTW,克隆了HelloScalaOnAndroid的項目后,別忘了在本地運行"android update project -p .",因為local.properties是需要在本地生成的。

    2,說明下我的改動:

    1)將本文的build-scala.xml改名為build-scala_2.9.2_r19.xml,它是其它文件的基礎。

    2)將本文的mac-shim.xml改名為build-scala_r19_patch_to_r21.xml。

    3)文件命名中,2.9.2不僅支持Scala  2.9.2,還支持2.9.3;而r21也不僅支持Android tools r21,也支持r21.1。

    4)build-scala_*_r21.xml中的內容,已經整合了build-scala_r19_patch_to_r21.xml的內容,所以如果使用它們,可以不再使用build-scala_r19_patch_to_r21.xml。

    5)因為現在Android Tools最新的版本就是r21.1,開發一般都是在最新的版本環境中的,所以可以直接拿build-scala_*_r21.xml使用,具體哪一個,要看使用的Scala的版本是2.9.x還是2.10.x。

    6)build-scala_2.10.0_*.xml中的內容,是針對Scala 2.10.x的版本所做的更新。與2.9.x的版本不兼容。

    7)將本文的proguard-template.cfg改名為proguard-template_2.9.2.cfg,表示只支持Scala 2.9.x版本;若想使用Scala  2.10.x,需要用proguard-template_2.10.0.cfg。

結束語


     至此,Windows下使用IDEA構建Scala on Android的開發環境,就全部完成了。至於如何使用Eclispe進行構建,我打算日后有時間再補上,不過Eclipse下的plugins要比IDEA豐富,而且我還沒有徹底使用Eclipse構建過,所以不保證什么時間,若沒有什么特別需要注意的地方,網上也能找到可用的參考,或許我就不寫了。我個人偏向於IDEA,計划寫Eclipse的部分,是想讓這個系列更完整。

    正如系列開篇時所說,這些內容只是適合初學者,至於函數式編程的深入理解,以及Scala語言的深入使用,都不是本文所涉及的。作為基礎部分,能幫到有意學習這些內容的朋友,已感高興,任何看法和建議,可以郵件聯系。謝謝~

返回索引


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM