精品欧美一区二区三区在线观看 _久久久久国色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)

日韩av手机在线看| 日韩欧美一二三四区| 亚洲精品成人自拍| 国产精品特级毛片一区二区三区| hd国产人妖ts另类视频| thepron国产精品| 日韩免费在线播放| 老司机成人免费视频| av不卡一区| 欧美四级电影网| 国产成人一区二区三区别| 青青草免费在线| 国产一区二区导航在线播放| 97高清免费视频| 久久日免费视频| 福利片在线一区二区| 91福利国产成人精品照片| 国产精品综合久久久久久| 无码人妻丰满熟妇区bbbbxxxx| 国产精品久久久久久久| 亚洲欧美日韩中文在线| 91精产国品一二三| 久久久久久一区二区三区四区别墅| 亚洲h在线观看| 桥本有菜av在线| 韩国三级在线观看久| 亚洲国产高清一区二区三区| 国产一区二区三区精品久久久| 俄罗斯女人裸体性做爰| www久久日com| 久久精品一区二区三区不卡| 99热在线国产| 91好色先生tv| 日韩专区欧美专区| 欧美最猛性xxxxx免费| 18精品爽视频在线观看| 亚洲高清影视| 综合网日日天干夜夜久久| 北条麻妃在线一区| 久久免费电影| 亚洲欧美激情插| 亚洲国产精品久久久久久女王| 亚洲欧美日韩综合在线| 国v精品久久久网| 亚洲淫片在线视频| 国产精品久久欧美久久一区| 蜜臀国产一区二区三区在线播放| 欧洲亚洲免费在线| www.国产毛片| 久久亚洲色图| 日本欧美在线视频| 中文字幕国产在线观看| 日韩电影一区| 亚洲天堂日韩电影| 日本乱子伦xxxx| 精品国产一区探花在线观看| 国产一区二区三区丝袜| 性欧美丰满熟妇xxxx性仙踪林| 精品亚洲免a| 亚洲精品99久久久久| 中文在线观看免费视频| 国产一区丝袜| 亚洲欧美日韩精品| jizz中文字幕| 日本精品三区| 久久久www成人免费精品| 老熟妇高潮一区二区三区| 天天综合精品| 欧美贵妇videos办公室| 亚洲国产精一区二区三区性色| 黄色av日韩| 91国内在线视频| 无码人妻丰满熟妇奶水区码| 麻豆视频一区二区| 91九色视频在线| 日韩欧美高清在线观看| aa亚洲婷婷| 欧美在线视频a| 狠狠躁夜夜躁人人爽视频| 美女视频黄 久久| 91深夜福利视频| 免费观看黄色av| 久久久噜噜噜久久中文字幕色伊伊| 奇米影视首页 狠狠色丁香婷婷久久综合| 欧洲一级在线观看| 国产精品九色蝌蚪自拍| 在线视频一区观看| 色呦呦在线看| 色婷婷国产精品综合在线观看| 中文字幕第88页| 97久久精品| 亚洲午夜久久久影院| √天堂中文官网8在线| 亚洲第一伊人| 国产精品视频yy9099| 亚洲av无码乱码在线观看性色| 91尤物视频在线观看| 亚洲精品在线免费看| 欧美一卡二卡| 欧美少妇性性性| 国产第一页视频| 999精品嫩草久久久久久99| 在线观看免费亚洲| 精品这里只有精品| 日韩精选视频| 日韩免费性生活视频播放| 中国美女乱淫免费看视频| 亚洲成人精品| 日本最新高清不卡中文字幕| jlzzjlzzjlzz亚洲人| 久久日韩精品一区二区五区| 国内自拍中文字幕| av在线一区不卡| 亚洲国产精品字幕| 黑鬼狂亚洲人videos| 天堂va蜜桃一区二区三区 | 久久一区二区三区av| 9191在线| 国产精品亲子伦对白| 日韩国产小视频| 开心久久婷婷综合中文字幕| 日韩成人在线视频| 欧美国产在线看| 美女视频黄免费的久久 | 一区二区三区在线免费| 99视频免费播放| 国产精品自在| 欧美黄色免费网站| 国产绿帽刺激高潮对白| 国产亚洲一区二区三区在线观看| 久久精品国产理论片免费| 超碰电影在线播放| 欧美日韩精品高清| 非洲一级黄色片| 亚洲免费综合| 精品日本一区二区三区| 青草青在线视频| 欧美一级免费大片| 无码国产69精品久久久久网站| 香蕉视频国产精品| 国产欧美一区二区三区视频| 精品av中文字幕在线毛片| 午夜久久久久久| www.啪啪.com| 在线免费观看欧美| 风间由美久久久| 黑人精品视频| 精品国产乱码久久久久久牛牛| 欧美精品久久久久性色| 中文精品在线| 国产伦精品一区二区三区视频黑人 | 无码免费一区二区三区免费播放 | 91久久久久久久久久| 免费成人黄色| 欧美精品电影在线播放| 日本一级片免费| 国产在线精品免费av| 国产高清免费在线| 精品一区二区三区中文字幕视频| 久久亚洲精品一区二区| 国产片在线播放| 亚洲精品日韩综合观看成人91| 三级黄色片播放| 在线观看一区| 久久av免费一区| 欧美成人h版| 日韩天堂在线视频| 99riav国产| 亚洲自拍偷拍av| 美女又爽又黄免费| 久久人人97超碰国产公开结果| 日本一区二区三区视频在线观看 | 国产精品国产精品国产专区不卡| 国产美女一区视频| 国产视频精品免费播放| 视频国产一区二区| 国产麻豆视频精品| 成人性免费视频| 精品国产一级毛片| 96pao国产成视频永久免费| 欧美大胆的人体xxxx| 亚洲国产欧美在线成人app| 亚洲第一网站在线观看| 国产精品福利一区| 国产ts在线观看| 久久久成人网| 青少年xxxxx性开放hg| 国产毛片精品| 国产精品高精视频免费| 色综合999| 亚洲片在线资源| 国产日韩在线观看一区| 欧美日韩视频在线| 99国产精品无码| 成人自拍视频在线| 男操女免费网站| 伊人久久大香线蕉av超碰演员| 日本一区精品| 国产另类在线| 成人看片人aa| 欧美一区二区三区| 亚洲第一男人天堂| 一本色道久久综合亚洲| 亚洲电影在线播放| 刘亦菲国产毛片bd| 97久久超碰精品国产| 欧洲在线免费视频| 午夜在线播放视频欧美| 日韩欧美一级在线| 精品国产一区二区三区久久久蜜臀| 操一操视频一区| 亚洲二区av| 国产成人精品一区二区在线| 韩国日本一区| 精品国偷自产在线| 国产高清视频在线播放| 欧美精品一区视频| 国产一区二区三区黄片| 亚洲综合视频网| 二区三区四区视频| 久久久www免费人成精品| 岛国精品一区二区三区| 另类小说综合欧美亚洲| 国产男女无遮挡| 一区免费视频| 欧美在线观看黄| 成人看片黄a免费看视频| 国产日韩欧美日韩| 美女福利一区二区| 97精品国产91久久久久久| 2024最新电影在线免费观看| 色悠悠久久88| 成人高清网站| 亚洲欧洲偷拍精品| 欧美白人做受xxxx视频| 日韩av在线播放资源| 黄色av网址在线| 日韩欧美一级二级三级 | 亚洲成人精品久久| 国产ts变态重口人妖hd| 337p亚洲精品色噜噜| 一区二区视频免费观看| 欧美性做爰猛烈叫床潮| 国产免费a视频| 亚洲区小说区图片区qvod| 色哟哟国产精品免费观看| 久草视频精品在线| 亚洲一区二区三区三| 国模无码国产精品视频| 亚洲品质自拍视频| 国内偷拍精品视频| 亚洲综合色在线| 日韩激情一区二区三区| 亚洲成人午夜影院| 中国一级免费毛片| 欧美三级免费观看| 中文字幕精品视频在线观看| 日本国产一区二区| 久久久久久av无码免费看大片| 欧美在线观看一区二区| 中文字幕乱码视频| 欧美高清一级片在线| 99久久精品国产色欲| 日韩一区二区在线观看| 亚洲第一天堂在线观看| 亚洲国产成人在线播放| 亚洲av成人无码久久精品老人| 国产视频一区在线| 成年女人的天堂在线| www.亚洲人.com| 1区2区3区在线视频| 97视频在线观看免费| videos性欧美另类高清| 国产精品视频久久久| 国产剧情一区二区在线观看| 国产高清精品一区| 欧美日本成人| 久久久国产精华液999999| 欧美涩涩网站| 久久精品国产美女| 精品一区在线| 一区视频二区视频| 极品裸体白嫩激情啪啪国产精品| 1024精品视频| 久久精品久久99精品久久| 精产国品一二三区| 99在线热播精品免费| 69久久夜色精品国产69乱青草| 神马精品久久| 色狠狠av一区二区三区香蕉蜜桃| 国产欧美久久久久久久久| 国内精品久久久久久影视8| 成人午夜精品| 999热视频| 精品欧美激情在线观看| 香蕉视频免费版| 午夜亚洲福利在线老司机| 日本人69视频| 91视频在线看| 风韵丰满熟妇啪啪区老熟熟女| 波多野结衣中文字幕一区二区三区| 91中文字幕永久在线| jiyouzz国产精品久久| 黄色片网站免费| 亚洲自拍偷拍欧美| 中文字幕人妻色偷偷久久| 日韩欧美亚洲国产精品字幕久久久| 美国成人毛片| 久久久女女女女999久久| 日本肉肉一区 | 精品三级av在线导航| 亚洲人成网站在线观看播放| 一本色道久久| 69久久精品无码一区二区| 国产亚洲欧美日韩俺去了| 久久婷婷一区二区| 在线不卡一区二区| 男女av在线| 97视频免费看| 9l视频自拍九色9l视频成人| 亚洲一区二区三区免费观看| 欧美专区在线| 免费日本黄色网址| 玉足女爽爽91| 国产乱色精品成人免费视频| 亚洲最大在线视频| 中国字幕a在线看韩国电影| 国产精品毛片一区视频| 一本一道久久a久久精品蜜桃| 日本黄色a视频| 久久精品一本| 最近日本中文字幕| 亚洲综合色视频| 99在线观看免费| 日韩在线小视频| 亚洲播播91| 欧美日韩精品久久| 亚洲女同在线| 自拍视频一区二区| 午夜精品一区二区三区三上悠亚| 懂色av蜜臀av粉嫩av分享吧| 久久91亚洲人成电影网站| 91精品一区| 欧美 另类 交| 国产精品综合av一区二区国产馆| 日韩美女主播在线视频一区二区三区| 亚洲精品一区二区三区四区| 久久久精品免费视频| 精品久久在线| 99精品一级欧美片免费播放| 国产精品69毛片高清亚洲| 99久久婷婷国产综合| 日韩区在线观看| 在线heyzo| 国产视频一区二区三区四区| 亚洲美女啪啪| 91精品人妻一区二区三区蜜桃欧美| 欧美日韩激情网| 国产在线一二三区| 国产精品爽爽爽| 欧美va亚洲va日韩∨a综合色| 香蕉视频色在线观看| 亚洲一区二区视频在线观看| 手机看片一区二区三区| 欧美制服第一页| heyzo久久| 老司机久久精品| 一区二区激情小说| 天堂中文字幕av| 日本精品在线视频| 国产精品久久天天影视| 色婷婷狠狠18禁久久| 欧美日韩国产在线播放| 欧美777四色影视在线| 国产精品美女免费视频| 亚洲精品tv久久久久久久久久| 日b视频免费观看| 91丨porny丨首页| 亚洲中文字幕在线观看| 欧美日韩第一页| 夜夜躁狠狠躁日日躁2021日韩| 一区二区三区视频网| 亚洲精品欧美激情| 三级视频网站在线| 国产这里只有精品| 在线精品在线| 国产精品无码无卡无需播放器| 日韩午夜激情免费电影| 九色porny自拍视频在线观看| 亚洲国产日韩综合一区| 国产成人福利片| 久久久久精彩视频| 国模精品一区二区三区色天香| 国产剧情一区| 日韩国产一级片| 国产婷婷色一区二区三区| 国产成人av免费看| 日本不卡视频在线播放| 真实国产乱子伦精品一区二区三区| 亚洲av成人无码一二三在线观看|