精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Scala+Eclipse+Android手機(jī)開發(fā)初探

開發(fā) 后端
在Android設(shè)備上運(yùn)行Scala編寫的移動(dòng)應(yīng)用軟件?本文介紹了Android SDK(v1.5)下使用Eclipse的Scala插件(v2.7.5)進(jìn)行移動(dòng)應(yīng)用開發(fā)的一些入門知識(shí)。

眾所周知Android平臺(tái)上可以跑Java,因此運(yùn)行在JVM之上的Scala也可以跑。在本文中,我們將創(chuàng)建一個(gè)在 Android 設(shè)備上運(yùn)行的移動(dòng)應(yīng)用程序。您將需要安裝 Android SDK;本文使用 V1.5 SDK。應(yīng)用程序代碼將用 Scala 編程語言編寫。如果您從來沒用過 Scala,那么沒有關(guān)系,因?yàn)楸疚膶⒔忉?Scala 代碼。但是,即使您不熟悉 Scala,建議您至少熟悉 Java 語言。本文使用 Scala V2.7.5 進(jìn)行開發(fā)。對(duì)于 Android 和 Scala 都提供了很好的 Eclipse 插件。本文使用 Eclipse V3.4.2 和 Android Development Tools(ADT) V0.9.1 以及 Scala IDE 插件 V2.7.5。

51CTO編輯推薦:Scala編程語言專題

設(shè)置

編寫 Android 應(yīng)用程序聽起來像是一個(gè)復(fù)雜的命題。Android 應(yīng)用程序在它們自己的虛擬機(jī)中運(yùn)行:Dalvik 虛擬機(jī)。但是,Android 應(yīng)用程序的構(gòu)建路徑是開放的。下面表明了我們將使用的基本策略。

圖 1. Android 上 Scala 的構(gòu)建路徑

Android 上 Scala 的構(gòu)建路徑 

其思想是,我們首先將所有 Scala 代碼編譯成 Java 類文件。這是 Scala 編譯器的工作,所以這方面沒什么太復(fù)雜的事情。接下來,獲取 Java 類文件,使用 Android dex 編譯器將類文件編譯成 Android 設(shè)備上的 Dalvik VM 使用的格式。這就是所謂的 dexing,也是 Android 應(yīng)用程序的常規(guī)編譯路徑。通常,要經(jīng)歷從 .java 文件到 .class 文件再到 .dex 文件的過程。在本文,惟一不同的是我們從 .scala 文件開始。***,.dex 文件和其他應(yīng)用程序資源被壓縮成一個(gè) APK 文件,該文件可安裝到 Android 設(shè)備上。

那么,如何讓這一切發(fā)生?我們將使用 Eclipse 做大部分工作。但是,此外還有一個(gè)較復(fù)雜的步驟:要讓代碼運(yùn)行,還需要來自標(biāo)準(zhǔn) Scala 庫中的代碼。在典型的 Scala 安裝中,這是 /lib/scala-library.jar 中一個(gè)單獨(dú)的 JAR。但是,這個(gè) JAR 包括一些不受 Android 支持的代碼。有些代碼需要稍作調(diào)整,有些代碼則必須移除。scala-library.jar 的定制構(gòu)建是運(yùn)行得***的,至少目前是這樣。請(qǐng)參閱 參考資料,了解這里使用的定制構(gòu)建。我們將把這個(gè) JAR 稱作 Android 庫 JAR。

有了這個(gè) JAR,剩下的事情就很容易了。只需使用 Eclipse 的 ADT 插件創(chuàng)建一個(gè) Android 項(xiàng)目。然后將一個(gè) Scala 特性(nature)添加到項(xiàng)目中。用前面談到的 Android 庫替代標(biāo)準(zhǔn)的 Scala 庫。***,將輸出目錄添加到類路徑中。現(xiàn)在,可以開始了。現(xiàn)在,我們有了基本的設(shè)置,接下來看看我們將使用 Scala 創(chuàng)建的 Android 應(yīng)用程序。

UnitsConverter

現(xiàn)在,我們知道如何利用 Scala 代碼,將它轉(zhuǎn)換成將在 Android 設(shè)備上運(yùn)行的二進(jìn)制格式,接下來可以使用 Scala 創(chuàng)建一個(gè)移動(dòng)應(yīng)用程序。我們將創(chuàng)建的應(yīng)用程序是一個(gè)簡單的單位轉(zhuǎn)換應(yīng)用程序。通過這個(gè)應(yīng)用程序可以方便地在英制單位與公制單位之間來回轉(zhuǎn)換。這是一個(gè)非常簡單的應(yīng)用程序,但是我們將看到,即使是最簡單的應(yīng)用程序也可以從使用 Scala 中獲益。我們首先看看 UnitsConverter 的布局元素。

創(chuàng)建布局

您也許對(duì)編寫手機(jī)上運(yùn)行的 Scala 感到興奮,但是并非所有的移動(dòng)開發(fā)編程都應(yīng)該用 Scala 或 Java 語言完成。Android SDK 提供了一種很好的方式,使用基于 XML 的布局系統(tǒng)將用戶界面代碼與應(yīng)用程序邏輯分離。我們來看看本文中的應(yīng)用程序的主要布局文件,如清單 1 所示。

清單 1. Converter 應(yīng)用程序的主要布局

< ?xml version="1.0" encoding="utf-8"?>
< RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:gravity="center_horizontal" android:padding="10px"
    >
    < TextView android:id="@+id/prompt_label" android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:text="@string/prompt_metric"/>
    < EditText android:id="@+id/amount" android:layout_below="@id/prompt_label"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"/>
    < TextView android:id="@+id/uom_label"  
        android:layout_below="@id/amount"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:text="@string/uom"/>
    < Spinner android:id="@+id/uom_value"
        android:layout_below="@id/uom_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    < Button android:id="@+id/convert_button"
        android:layout_below="@id/uom_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/convert_button_label"/>
    < TextView android:id="@+id/result_value"
        android:layout_below="@id/convert_button"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>        
< /RelativeLayout>

以上代碼非常簡潔地創(chuàng)建了該應(yīng)用程序的主 UI。它的根節(jié)點(diǎn)是一個(gè) RelativeLayout 容器元素。Android SDK 中有很多布局選項(xiàng)。RelativeLayout 指示運(yùn)行時(shí)使用相對(duì)定位對(duì)不同的 UI 小部件進(jìn)行布局。要使用相對(duì)定位,可添加可見元素 — 在這里是一個(gè) TextView 元素。這是用于顯示文本的一個(gè)簡單的元素。它被賦予一個(gè) ID prompt_label。接下來的元素,即一個(gè) EditText 元素(一個(gè)文本輸入框)將用到它。這個(gè)元素有一個(gè) layout_below 屬性,它的值等于 prompt_label ID。換句話說,EditText 應(yīng)該放在名為 prompt_label 的元素的下方。

布局代碼剩下的部分非常簡單。有一個(gè)帶標(biāo)簽的文本輸入框、一個(gè)帶標(biāo)簽的微調(diào)器(一個(gè)組合框或下拉框)、一個(gè)按鈕和一個(gè)用于輸出的文本框。圖 2 顯示正在運(yùn)行的應(yīng)用程序的一個(gè)截圖,其中標(biāo)出了不同的元素。

圖 2. Android lLayout — 分解圖

Android lLayout -- 分解圖

那么,以上視圖中看到的不同文本值來自哪里呢?注意,清單 1 中的一些元素有一個(gè) text 屬性。例如,prompt_label 元素有一個(gè)等于 @string/prompt_metric 的 text 屬性。這表明它將使用 Android 應(yīng)用程序中一個(gè)標(biāo)準(zhǔn)的資源文件:strings.xml 文件,如清單 2 所示。

清單 2. strings.xml 資源

< ?xml version="1.0" encoding="utf-8"?>
< resources>
    < string name="prompt_metric">Enter amount (KM, g, L, C)< /string>
    < string name="prompt_english">Enter amount (miles, lbs, gallons,F)< /string>
    < string name="uom">Units of Measure< /string>
    < string name="convert_button_label">Convert< /string>
    < string name="app_name">Converter< /string>
    < string name="english_units">English< /string>
    < string name="metric_units">Metric< /string>
< /resources>

現(xiàn)在可以看到,圖 2 中所有的文本來自何處。微調(diào)器有一個(gè)下拉框,其中包含可用于度量的單位,那些單位在清單 2 中沒有列出。相反,它們來自另一個(gè)文件 arrays.xml,如清單 3 所示。

清單 3. arrays.xml 資源

< ?xml version="1.0" encoding="utf-8"?>
< resources>
    < array name="english_units">
        < item>Fahrenheit< /item>
        < item>Pounds< /item>
        < item>Ounces< /item>
        < item>Fluid Ounces< /item>
        < item>Gallons< /item>
        < item>Miles< /item>
        < item>Inches< /item>
    < /array>
    < array name="metric_units">
        < item>Celsius< /item>
        < item>Kilograms< /item>
        < item>Grams< /item>
        < item>Millileters< /item>
        < item>Liters< /item>
        < item>Kilometers< /item>
        < item>Centimeters< /item>
    < /array>    
< /resources>

現(xiàn)在,我們可以看到將用于微調(diào)器的那些值。那么,這些值如何出現(xiàn)在微調(diào)器中,應(yīng)用程序如何在英制單位與公制單位之間切換?要回答這些問題,我們需要看看應(yīng)用程序代碼本身。

Scala 應(yīng)用程序代碼

Converter 應(yīng)用程序的代碼非常簡單 — 不管用什么語言編寫。當(dāng)然,用 Java 編寫起來非常容易,但是用 Scala 編寫也同樣不復(fù)雜。首先我們看看前面見過的 UI 背后的代碼。

視圖背后的代碼

解釋創(chuàng)建 UI 的 Scala 代碼的最簡單方式是先看看代碼,然后走查一遍。對(duì)于任何應(yīng)用程序,都是在應(yīng)用程序的 AndroidManifest.xml 文件中定義應(yīng)用程序的默認(rèn)活動(dòng)。任何 UI 背后都有一個(gè) Activity 類,默認(rèn)的 Activity 定義當(dāng)應(yīng)用程序初次裝載時(shí)執(zhí)行的 Activity 類。對(duì)于像本文這樣簡單的應(yīng)用程序,有一個(gè) Converter 類,清單 4 中顯示了它的源代碼。

清單 4. Converter 活動(dòng)類

class Converter extends Activity{
    import ConverterHelper._
    private[this] var amountValue:EditText = null
    private[this] var uom:Spinner= null
    private[this] var convertButton:Button = null
    private[this] var resultValue:TextView = null
    
    override def onCreate(savedInstanceState:Bundle){
      super.onCreate(savedInstanceState)
      setContentView(R.layout.main)
      uom = findViewById(R.id.uom_value).asInstanceOf[Spinner]
      this.setUomChoice(ENGLISH)
      amountValue = findViewById(R.id.amount).asInstanceOf[EditText]
      convertButton = findViewById(R.id.convert_button).asInstanceOf[Button]
      resultValue = findViewById(R.id.result_value).asInstanceOf[TextView]
      convertButton.setOnClickListener( () => {
          val unit = uom.getSelectedItem.asInstanceOf[String]
          val amount = parseDouble(amountValue.getText.toString)
          val result = UnitsConverter.convert(Measurement(unit,amount))
          resultValue.setText(result)
      })
    }
    override def onCreateOptionsMenu(menu:Menu) = {
      super.onCreateOptionsMenu(menu)
      menu.add(NONE, 0, 0, R.string.english_units)
      menu.add(NONE, 1, 1, R.string.metric_units)
      true
    }
    override def onMenuItemSelected(featureId:Int, item:MenuItem) = {
      super.onMenuItemSelected(featureId, item)
      setUomChoice(if (item.getItemId == 1) METRIC else ENGLISH)
      true
    }
    private 
    def setUomChoice(unitOfMeasure:UnitsSystem){
      if (uom == null){
        uom = findViewById(R.id.uom_value).asInstanceOf[Spinner]
      }
      val arrayId = unitOfMeasure match {
        case METRIC => R.array.metric_units
        case _ => R.array.english_units
      }
      val units = new ArrayAdapter[String](this, R.layout.spinner_view, 
        getResources.getStringArray(arrayId))
      uom.setAdapter(units)      
    }
}

我們從這個(gè)類的頂部開始。它擴(kuò)展 android.app.Activity。這是一個(gè) Java 類,但是從 Scala 中可以對(duì) Java 類輕松地進(jìn)行細(xì)分。接下來,它有一些實(shí)例變量。每個(gè)實(shí)例變量對(duì)應(yīng)前面定義的一個(gè) UI 元素。注意,每個(gè)實(shí)例變量還被限定為 private[this]。這演示了 Scala 中特有的一種訪問控制級(jí)別,而 Java 語言中不存在這種訪問控制。這些變量不僅是私有的,而且只屬于 Converter 類的特定實(shí)例。這種級(jí)別的訪問控制對(duì)于移動(dòng)應(yīng)用程序來說有些大材小用,但是如果您是一名 Scala 開發(fā)人員,可以放心地在 Android 應(yīng)用程序上使用您熟悉的語法。

回到清單 4 中的代碼,注意,我們覆蓋了 onCreate 方法。這是 Activity 類中定義的方法,通常被定制的 Activity 覆蓋。如果用 Java 語言編寫該代碼,那么應(yīng)該添加一個(gè) @Override 標(biāo)注。在 Scala 中,override 是一個(gè)關(guān)鍵詞,用于確保正確性。這樣可以防止誤拼方法名之類的常見錯(cuò)誤。如果誤拼了方法名,Scala 編譯器將捕捉到方法名并返回一個(gè)錯(cuò)誤。注意,在這個(gè)方法上,以及任何其他方法上,不需要聲明返回類型。Scala 編譯器可以輕松推斷出該信息,所以不需要多此一舉。

onCreate 中的大部分代碼類似于 Java 語言編寫的代碼。但是有幾點(diǎn)比較有趣。注意,我們使用 findViewById 方法(在 Activity 子類中定義)獲得不同 UI 元素的句柄。這個(gè)方法不是類型安全的,需要進(jìn)行類型轉(zhuǎn)換(cast)。在 Scala 中,要進(jìn)行類型轉(zhuǎn)換,可使用參數(shù)化方法 asInstanceOf[T],其中 T 是要轉(zhuǎn)換的類型。這種轉(zhuǎn)換在功能上與 Java 語言中的轉(zhuǎn)換一樣。不過 Scala 有更好的語法。接下來,注意對(duì) setUomChoice 的調(diào)用(稍后我們將詳細(xì)談到這個(gè)方法)。***,注意上述代碼獲得一個(gè)在布局 XML 中創(chuàng)建的按鈕的句柄,并添加一個(gè)單擊事件處理程序。

如果用 Java 語言編寫,那么必須傳入 Android 接口 OnClickListener 的一個(gè)實(shí)現(xiàn)。這個(gè)接口只定義一個(gè)方法:onClick。實(shí)際上,您關(guān)心的只是那個(gè)方法,但是在 Java 語言中無法直接傳入方法。而在 Scala 中則不同,在 Scala 中可以傳入方法字面量(literal)或閉包。在這里,我們用語法 () => { ... } 表示閉包,其中方法的主體就是花括號(hào)中的內(nèi)容。開始/結(jié)束括號(hào)表示一個(gè)不帶參數(shù)的函數(shù)。但是,我將這個(gè)閉包傳遞到 Button 的一個(gè)實(shí)例上的 setOnClickListener 方法,Button 是 Android SDK 中定義的一個(gè) Java 類。如何將 Scala 閉包傳遞到 Java API?我們來看看。

Android 上的函數(shù)式編程

為了理解如何讓 Android API 使用函數(shù)字面量,看看 Converter 類定義的***行。這是一條重要的語句。這是 Scala 的另一個(gè)很好的特性。您可以在代碼的任何地方導(dǎo)入包、類等,它們的作用域限于導(dǎo)入它們的文件。在這里,我們導(dǎo)入 ConverterHelper 中的所有東西。清單 5 顯示 ConverterHelper 代碼。

清單 5. ConverterHelper

object ConverterHelper{
  import android.view.View.OnClickListener
  implicit def funcToClicker(f:View => Unit):OnClickListener = 
    new OnClickListener(){ def onClick(v:View)=f.apply(v)}
  implicit def funcToClicker0(f:() => Unit):OnClickListener = 
    new OnClickListener() { def onClick(v:View)=f.apply}
}

這是一個(gè) Scala 單例(singleton),因?yàn)樗褂脤?duì)象聲明,而不是類聲明。單例模式被直接內(nèi)置在 Scala 中,可以替代 Java 語言中的靜態(tài)方法或變量。在這里,這個(gè)單例存放一對(duì)函數(shù):funcToClicker 和 funcToClicker0。這兩個(gè)函數(shù)以一個(gè)函數(shù)作為輸入?yún)?shù),并返回 OnClickListener 的一個(gè)實(shí)例,OnClickListener 是 Android SDK 中定義的一個(gè)接口。例如,funcToClicker 被定義為以一個(gè)函數(shù) f 為參數(shù)。這個(gè)函數(shù) f 的類型為帶一個(gè) View 類型(Android 中的另一個(gè)類)的輸入?yún)?shù)的函數(shù),并返回 Unit,它是 void 在 Scala 中的對(duì)等物。然后,它返回 OnClickListener 的一個(gè)實(shí)現(xiàn),在這個(gè)實(shí)現(xiàn)中,該接口的 onClick 方法被實(shí)現(xiàn)為將輸入函數(shù) f 應(yīng)用到 View 參數(shù)。另一個(gè)函數(shù) funcToClick0 也做同樣的事情,只是以一個(gè)不帶輸入?yún)?shù)的函數(shù)為參數(shù)。

這兩個(gè)函數(shù)(funcToClicker 和 funcToClicker0)都被定義為隱式函數(shù)(implicit)。這是 Scala 的一個(gè)方便的特性。它可以讓編譯器隱式地將一種類型轉(zhuǎn)換成另一種類型。在這里,當(dāng)編譯器解析 Converter 類的 onCreate 方法時(shí),它遇到一個(gè) setOnClickListener 調(diào)用。這個(gè)方法需要一個(gè) OnClickListener 實(shí)例。但是,編譯器卻發(fā)現(xiàn)一個(gè)函數(shù)。在報(bào)錯(cuò)并出現(xiàn)編譯失敗之前,編譯器將檢查是否存在隱式函數(shù),允許將函數(shù)轉(zhuǎn)換為 OnClickListener。由于確實(shí)還有這樣的函數(shù),所以它執(zhí)行轉(zhuǎn)換,編譯成功。現(xiàn)在,我們理解了如何使用 Android 中的閉包,接下來更仔細(xì)地看看應(yīng)用程序邏輯 — 特別是,如何執(zhí)行單位轉(zhuǎn)換計(jì)算。

單位轉(zhuǎn)換和計(jì)算

我們回到清單 4。傳入 onClickListener 的函數(shù)收到用戶輸入的度量單位和值。然后,它創(chuàng)建一個(gè) Measurement 實(shí)例,并將該實(shí)例傳遞到一個(gè) UnitsConverter 對(duì)象。清單 6 顯示相應(yīng)的代碼。

清單 6. Measurement 和 UnitsConverter

case class Measurement(uom:String, amount:Double)

object UnitsConverter{
      // constants
    val lbToKg = 0.45359237D
      val ozToG = 28.3495231
      val fOzToMl = 29.5735296
      val galToL = 3.78541178
      val milesToKm = 1.609344
      val inchToCm = 2.54  
   
      def convert (measure:Measurement)= measure.uom match {
          case "Fahrenheit" => (5.0/9.0)*(measure.amount - 32.0) + " C"
            case "Pounds" => lbToKg*measure.amount + " kg"
            case "Ounces" => ozToG*measure.amount + " g"
            case "Fluid Ounces" => fOzToMl*measure.amount + " mL"
            case "Gallons" => galToL*measure.amount + " L"
            case "Miles" => milesToKm*measure.amount + " km"
            case "Inches" => inchToCm*measure.amount + " cm"
            case "Celsius" => (9.0/5.0*measure.amount + 32.0) + " F"
            case "Kilograms" => measure.amount/lbToKg + " lbs"
            case "Grams" => measure.amount/ozToG + " oz"
            case "Millileters" => measure.amount/fOzToMl + " fl. oz."
            case "Liters" => measure.amount/galToL + " gallons"
            case "Kilometers" => measure.amount/milesToKm + " miles"
            case "Centimeters" => measure.amount/inchToCm + " inches"
            case _ => ""
      }
}

Measurement 是一個(gè) case 類。這是 Scala 中的一個(gè)方便的特性。用 “case” 修飾一個(gè)類會(huì)導(dǎo)致這個(gè)類生成這樣一個(gè)構(gòu)造函數(shù):這個(gè)構(gòu)造函數(shù)需要類的屬性,以及 equals、 hashCode 和 toString 的實(shí)現(xiàn)。它對(duì)于像 Measurement 這樣的數(shù)據(jù)結(jié)構(gòu)類非常適合。它還為定義的屬性(在這里就是 uom 和 amount)生成 getter 方法。也可以將那些屬性定義為 vars(可變變量),然后也會(huì)生成 setter 方法。僅僅一行 Scala 代碼可以做這么多事情!

接下來,UnitsConverter 也是一個(gè)單例模式,因?yàn)樗鞘褂?object 關(guān)鍵詞定義的。它只有一個(gè) convert 方法。注意,convert 被定義為相當(dāng)于一條單一語句 — 一條 match 語句。它是一個(gè)單一表達(dá)式,所以不需要額外的花括號(hào)。它使用 Scala 的模式匹配。這是函數(shù)式編程語言中常見的一個(gè)強(qiáng)大特性。它類似于 Java 語言和很多其他語言中的 switch 語句。但是,我們可以匹配字符串(實(shí)際上,還可以有比這高級(jí)得多的匹配)。如果字符串匹配,則執(zhí)行適當(dāng)?shù)挠?jì)算,并返回格式化的字符串,以供顯示。***,注意與 _ 匹配的***一個(gè) case。Scala 中的很多地方使用下劃線作為通配符。在這里,它表示匹配任何東西,這類似于 Java 語言中的 default 語句。

現(xiàn)在,我們理解了應(yīng)用程序中的計(jì)算,***來看看剩下的 UI 設(shè)置和菜單。

UI 初始化和菜單

回到清單 4。我們說過要看看 setUomChoice。這個(gè)方法被定義為帶有一個(gè) UnitsSystem 類型的參數(shù)。我們來看看如何定義這個(gè)類型。

清單 7. UnitsSystem

sealed case class UnitsSystem()
case object ENGLISH extends UnitsSystem
case object METRIC extends UnitsSystem

我們看到,UnitsSystem 是一個(gè)密封的 case 類,沒有屬性。看上去它不是很有用。接下來,我們看看兩個(gè) case 對(duì)象。還記得嗎,object 表示 Scala 中的一個(gè)單例。在這里,有兩個(gè) case 對(duì)象,每個(gè) case 對(duì)象都擴(kuò)展 UnitsSystem。這是 Scala 中的一個(gè)常見的特色,它可以提供更簡單、更類型安全的枚舉方式。

現(xiàn)在 setUomChoice 的實(shí)現(xiàn)更加合理。在獲得微調(diào)器的一個(gè)句柄后,我們匹配傳入的 UnitsSystem 的類型。這標(biāo)識(shí)了我們?cè)谇懊嬉姷降?arrays.xml 中的一個(gè)數(shù)組。這是使用 Android SDK 生成的 R 類表示資源,例如 arrays.xml 文件。一旦知道使用哪個(gè)數(shù)組,我們就通過創(chuàng)建一個(gè)傳入微調(diào)器的適配器(在這里是一個(gè) ArrayAdapter),使用那個(gè)數(shù)組作為微調(diào)器的數(shù)據(jù)源。

***,看看清單 4 中的 onCreateOptionsMenu 和 onMenuItemSelected 方法。這些方法是在 Activity 中定義的,我們將在 Converter 活動(dòng)中覆蓋這些方法。***個(gè)方法創(chuàng)建一個(gè)菜單。第二個(gè)方法處理用戶從菜單中選擇 English 或 metric 的事件。它再次調(diào)用 setUomChoice。這使用戶可以在從英制單位轉(zhuǎn)換為公制單位與從公制單位轉(zhuǎn)換為英制單位之間進(jìn)行切換。

結(jié)束語

Android 平臺(tái)的架構(gòu)使它可以用于在 Java 虛擬機(jī)上運(yùn)行的任何編程語言。我們看到了如何設(shè)置 Android 項(xiàng)目,使它使用 Scala 代碼。這個(gè)過程也可以延伸到其他 JVM 編程語言,例如 Groovy、JRuby 或 Fan。當(dāng)可以任意使用 Scala 編程語言時(shí),編寫 Android 應(yīng)用程序?qū)⒆兊酶p松。您仍可以使用 Eclipse 進(jìn)行開發(fā)。仍然可以在 Eclipse 中用模擬器和設(shè)備進(jìn)行調(diào)試。您可以繼續(xù)使用所有的工具,同時(shí)又得到一種生產(chǎn)率更高的編程語言。

【相關(guān)閱讀】

  1. Scala編程語言專題
  2. 十二步學(xué)會(huì)Scala(2):Scala的循環(huán)和數(shù)組
  3. 從Java走進(jìn)Scala(Scala經(jīng)典讀物)
  4. Scala代碼實(shí)例之Kestrel:文章匯總
  5. Java開發(fā)人員指南:Scala + Twitter = Scitter
責(zé)任編輯:yangsai 來源: IBMDW
相關(guān)推薦

2012-06-08 09:28:15

EclipseScalaAndroid

2011-06-16 10:25:29

AndroidAIR

2009-07-08 17:40:28

ScalaScala腳本

2009-07-08 16:52:29

ScalaScala教程

2011-09-13 17:15:58

Eclipse And

2011-09-13 17:03:16

Eclipse And

2009-04-30 10:08:38

ScalaIDEEclipse

2010-08-11 10:58:06

AndroidAndroid NDK

2009-06-03 16:12:41

Eclipse開發(fā)AnAndroidEclipse

2011-12-12 10:57:31

JavaEclipse

2009-08-07 10:27:45

Eclipse和Net

2012-07-09 10:22:28

Mono for An

2017-01-15 18:32:39

Openresty架構(gòu)性能

2009-03-12 10:22:27

EclipseJ2MEJDT

2012-02-28 10:33:27

Eclipse 3.7Android環(huán)境

2010-09-25 09:31:27

EclipseAndroid

2011-09-13 18:14:23

Android SDK

2011-09-13 17:52:37

Eclipse And

2011-03-18 19:50:32

ScalaJVMQt

2012-03-16 13:43:29

點(diǎn)贊
收藏

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

欧美卡一卡二| 国产又大又黄又爽| 国产一区二区在线视频你懂的| 激情综合电影网| 精品成人a区在线观看| 欧美成人高潮一二区在线看| 神马久久久久久久久久| 羞羞答答国产精品www一本| 永久免费精品影视网站| 一本岛在线视频| av在线看片| 97精品久久久午夜一区二区三区| 久久久精品视频在线观看| 在线观看欧美一区二区| 91超碰在线| 欧美激情一区不卡| www.久久艹| 亚洲第一网站在线观看| 亚洲成av人电影| 日韩精品在线影院| 亚洲第一色av| 中文在线免费视频| 亚洲视频精选在线| 久热这里只精品99re8久| 一区二区日韩在线观看| 亚洲国产欧美国产综合一区| 少妇精69xxtheporn| 极品白嫩少妇无套内谢| 国内精品伊人| 精品成人在线视频| 91视频成人免费| 国产视频精品久久| 北条麻妃国产九九精品视频| 国产欧美日韩丝袜精品一区| 精品91久久久| 欧美va天堂在线| 怡红院精品视频| 手机av免费看| 久久香蕉精品香蕉| 欧美一区二区三区小说| 另类小说第一页| 亚洲伊人av| 亚洲va欧美va国产va天堂影院| 亚洲free性xxxx护士白浆| 日韩网红少妇无码视频香港| 亚洲免费二区| 日韩中文字幕免费看| 受虐m奴xxx在线观看| 999国产精品一区| 欧美裸体bbwbbwbbw| 国产精品人人妻人人爽人人牛| 波多野结衣一区二区| 91在线观看高清| 国产精品对白一区二区三区| 国产精品一区二区人人爽| 日韩av一级电影| 国产成人啪精品视频免费网| 黄色一级片免费看| 韩日在线一区| 欧美激情一区二区三级高清视频| 美女又爽又黄视频毛茸茸| 国产成人精品福利| 欧美tk—视频vk| 年下总裁被打光屁股sp| 亚洲综合网站| 欧美videossexotv100| 精品国产免费久久久久久婷婷| 自由日本语热亚洲人| 亚洲一二三区在线观看| 欧美一级免费播放| 黄色18在线观看| 精品日本高清在线播放| 久久免费视频3| 成人性生交大片免费网站| 日韩欧美在线看| 国内自拍视频一区| 精品乱码一区二区三区四区| 欧美精选在线播放| 污污视频网站在线| 中文字幕一区二区三区四区久久| 色哟哟国产精品| 无码少妇一区二区三区芒果| 粉嫩91精品久久久久久久99蜜桃| 亚洲va在线va天堂| 日本少妇高潮喷水视频| 芒果视频成人app| 欧美综合亚洲图片综合区| 婷婷免费在线观看| 精品久久免费| 日韩av网址在线| 中文字幕免费视频| 午夜av一区| 久久久久久久久国产| 九九热精品视频在线| 日韩成人一级大片| 97超碰最新| 欧美在线观看在线观看| 国产精品久久久久aaaa樱花| 国产小视频免费| 欧美momandson| 91超碰这里只有精品国产| 欧美日韩一区二区区别是什么| 国产一区精品福利| 精品国产sm最大网站免费看| 四虎影成人精品a片| 色琪琪久久se色| 欧美国产乱视频| 国产免费一区二区三区四区五区| 亚洲欧美高清| 成人黄色免费片| 天堂在线中文网| 中文字幕在线一区免费| 大西瓜av在线| 成人精品一区二区三区电影| 欧美第一区第二区| 懂色av蜜桃av| 亚洲精品美女91| 成人免费看吃奶视频网站| 污视频软件在线观看| 中文字幕一区二区三区不卡在线 | 亚洲人体一区| 不卡一本毛片| 欧美日韩国产免费一区二区| 久久人人爽人人人人片| 中文乱码免费一区二区三区下载| 久久久精品影院| 国产亚洲欧美在线精品| 国产超碰在线一区| 午夜啪啪免费视频| 日韩一区二区三区免费| 亚洲国产精品va在线观看黑人| 中国黄色片视频| 99久久夜色精品国产亚洲狼| 青青久久aⅴ北条麻妃| 亚洲国产精彩视频| 国产精品久久夜| 精品免费国产一区二区| 精品亚洲精品| 久久久噜久噜久久综合| 国产片在线播放| 亚洲国产精品成人久久综合一区 | 国产成人av免费观看| 不卡中文一二三区| 国产成人精品国内自产拍免费看| 波多野结衣视频免费观看| 99久久免费精品高清特色大片| 明星裸体视频一区二区| 高清在线视频不卡| 精品成人一区二区| 国产黄色片视频| 国产成人99久久亚洲综合精品| 噜噜噜噜噜久久久久久91| 日本一本在线免费福利| 欧美一级理论性理论a| 美国黄色片视频| 国内精品伊人久久久久av一坑 | 精品国产18久久久久久二百| 亚洲网站在线观看| 国产成人a v| 国产欧美日韩综合| 丰满少妇在线观看| 成人黄色av| 国产在线精品一区免费香蕉| 日韩精品成人av| 欧美猛男gaygay网站| 一本色道久久88| 久久99热狠狠色一区二区| 一区国产精品| www.久久草.com| 欧美精品一区在线播放| 亚洲精选一区二区三区| 午夜精品一区在线观看| 精品无码人妻一区| 日本免费在线视频不卡一不卡二| 国产高清精品一区| 久久青草伊人| 国产香蕉精品视频一区二区三区 | av亚洲天堂网| 99精品视频在线| 91嫩草国产在线观看| 好久没做在线观看| 日韩精品视频免费专区在线播放| 免费一级suv好看的国产网站| 激情欧美丁香| 蜜桃传媒视频麻豆第一区免费观看 | 欧美精品在欧美一区二区少妇| 亚洲av成人片色在线观看高潮| 亚洲国产一区二区在线观看 | 久久影院午夜精品| 亚洲色在线视频| 最近中文字幕在线观看视频| 自拍偷拍亚洲欧美日韩| 中文字幕一区二区三区人妻在线视频| 精品精品99| 91网免费观看| av资源亚洲| 美女福利精品视频| 欧美 日韩 国产 在线| 91成人在线精品| 999精品在线视频| 成人动漫在线一区| 最新中文字幕免费视频| 欧美日韩一卡| 日韩欧美三级一区二区| 欧美一区一区| 国产91精品在线播放| 怡红院在线播放| 亚洲天堂av电影| 亚洲va久久久噜噜噜无码久久| 亚洲同性gay激情无套| 亚洲少妇18p| 蜜桃av一区二区在线观看| 青草视频在线观看视频| 日韩www.| 久久综合久久综合这里只有精品| 美女福利一区二区| 欧美精品一本久久男人的天堂| 99热精品在线播放| 色老综合老女人久久久| 国产小视频在线看| 中文字幕在线一区| www.99热| 成人av手机在线观看| 亚洲18在线看污www麻豆 | 丝袜人妻一区二区三区| 欧美日韩中文字幕一区二区三区| 国产成人精品免费久久久久| 曰本三级在线| 日韩中文字幕视频在线| 欧美日韩国产亚洲沙发| 精品99一区二区| 国产女18毛片多18精品| 色婷婷av一区二区三区gif | 国产精品日韩无码| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 欧美丰满高潮xxxx喷水动漫| 亚洲av中文无码乱人伦在线视色| 国产午夜久久久久| 波多野结衣视频播放| 国产黄色精品网站| 在线免费看污网站| 久久99热国产| 久国产精品视频| 美女视频网站黄色亚洲| 妺妺窝人体色www在线观看| 国产亚洲精品bv在线观看| 日韩视频免费播放| 激情久久一区| 99在线观看视频免费| 国产精品99一区二区| 无码人妻精品一区二区三区99v| 伦理一区二区| 国产精品免费在线| 美女呻吟一区| 精品亚洲欧美日韩| 天天躁日日躁狠狠躁欧美| 国产一区二区三区四区五区在线 | 日本精品久久久久影院| √8天堂资源地址中文在线| 欧美激情一区二区三区成人| 久草在线视频网站| 午夜精品久久17c| av日韩中文| 4438全国亚洲精品在线观看视频| 三区四区在线视频| 久久精品国产精品亚洲| 国产精品剧情| 欧美剧在线观看| av毛片在线免费看| 久久久久久国产免费| 色多多在线观看| 国产98色在线| 亚洲精品成a人ⅴ香蕉片| 91天堂在线视频| 99亚洲乱人伦aⅴ精品| 精品国产_亚洲人成在线| 国产无遮挡裸体免费久久| 精品乱码一区二区三区| 一区二区小说| 亚洲精品白虎| 欧美欧美全黄| 国产最新免费视频| 美女一区二区三区在线观看| 原创真实夫妻啪啪av| av资源站一区| 亚洲一级片在线播放| 亚洲精品成人a在线观看| 国产成人亚洲精品自产在线| 色呦呦一区二区三区| 国产精品热久久| 亚洲成av人影院在线观看| 日本福利在线观看| 最近2019年中文视频免费在线观看| 欧美91精品久久久久国产性生爱| 精品福利二区三区| 国产原创av在线| 久久精品99国产精品酒店日本 | 久久蜜桃香蕉精品一区二区三区| 中文字幕永久免费| 国产日韩欧美麻豆| 亚洲国产精品免费在线观看| 亚洲高清免费观看| 中文字幕人妻一区二区在线视频| 色婷婷久久久综合中文字幕| 国产又黄又粗又猛又爽| 亚洲国模精品私拍| 午夜伦理在线| 97人人爽人人喊人人模波多 | 国产成人av网| 欧美久久亚洲| 亚洲bbw性色大片| 99re国产精品| 无套内谢丰满少妇中文字幕| 91免费小视频| 青青操视频在线播放| 在线中文字幕一区| 色欲av永久无码精品无码蜜桃| 亚洲成人av片| 麻豆传媒视频在线观看免费| 777精品视频| 一区中文字幕| 一区二区三区的久久的视频| 免费在线成人| 污污免费在线观看| 一区av在线播放| 96日本xxxxxⅹxxx17| 亚洲图片欧美午夜| 在线观看v片| 国产偷久久久精品专区| 亚洲一区二区三区| 91国产精品视频在线观看| 26uuu国产在线精品一区二区| 极品人妻videosss人妻| 欧美日韩国产区| www.com欧美| 久久视频在线直播| 日韩免费大片| 视频一区在线免费观看| 麻豆九一精品爱看视频在线观看免费| 污污动漫在线观看| 国产亚洲一本大道中文在线| 可以在线观看av的网站| 精品国产乱码久久久久久久久| 色播色播色播色播色播在线 | 高清视频一区| 欧美.www| 一级片黄色免费| 国产精品毛片a∨一区二区三区| 免费网站看av| 欧美一区二区三区四区久久 | 少妇精品视频一区二区免费看| 国产精品偷伦视频免费观看国产| 日韩欧洲国产| 久久亚洲a v| 粉嫩蜜臀av国产精品网站| 99精品久久久久| 日韩午夜电影av| 欧洲黄色一区| 国产免费一区二区三区| 99成人在线| 精品无码一区二区三区| 色婷婷综合激情| 在线视频二区| 91久久久久久久久| 午夜激情一区| 不许穿内裤随时挨c调教h苏绵| 国产精品丝袜一区| 国产尤物在线观看| 欧美日韩福利视频| 老牛精品亚洲成av人片| 国产精品第12页| 日本一区二区三区久久久久久久久不| 日本免费一二三区| 亚洲精品自在久久| 国产精成人品2018| 亚洲第一综合网站| 成人网在线播放| 一级片视频在线观看| 最新国产精品亚洲| 免费看日产一区二区三区| 性高湖久久久久久久久aaaaa| 九九精品视频在线看| 黄色一级视频免费观看| 亚洲国产精品高清久久久| 免费观看欧美大片| 综合久久国产| 97se亚洲国产综合在线| 中文字幕 视频一区| 欧美美女15p| 奇米狠狠一区二区三区| 中文字幕亚洲影院| 精品久久香蕉国产线看观看亚洲 | 日本a在线观看| 亚洲欧美日韩在线一区| 91精品一区| 欧美日韩黄色一级片| 国产精品区一区二区三区| 亚洲第一页视频| 国产99久久精品一区二区 夜夜躁日日躁| 国语一区二区三区|