Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the method of Scala+Eclipse+Android mobile phone development?

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the relevant knowledge of "what is the method of Scala+Eclipse+Android mobile phone development". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

It is well known that Java can be run on the Android platform, so Scala running on JVM can also run. In this article, we will create a mobile application that runs on an Android device. You will need to install Android SDK; for this article using V1.5 SDK. The application code will be written in Scala programming language. If you've never used Scala, it doesn't matter, because this article explains the Scala code. However, even if you are not familiar with Scala, it is recommended that you at least be familiar with the Java language. This article uses Scala V2.7.5 for development. Good Eclipse plug-ins are available for both Android and Scala. This article uses Eclipse V3.4.2 and Android Development Tools (ADT) V0.9.1 and the Scala IDE plug-in V2.7.5.

Set up

Writing Android applications sounds like a complex proposition. Android applications run in their own virtual machines: Dalvik virtual machines. However, the build path for Android applications is open. The basic strategy we will use is shown below.

Figure 1. Build path of Scala on Android

The idea is that we first compile all the Scala code into a Java class file. This is the job of the Scala compiler, so it's not too complicated. Next, get the Java class file and use the Android dex compiler to compile the class file into the format used by Dalvik VM on the Android device. This is called dexing, and it is also the regular compilation path for Android applications. Typically, you go through the process from .java files to .class files and then to .dex files. In this article, the only difference is that we start with the .scala file. The *, .dex file and other application resources are compressed into an APK file that can be installed on the Android device.

So how do you make this happen? We will use Eclipse to do most of the work. However, there is another more complex step: for the code to run, you also need code from the standard Scala library. In a typical Scala installation, this is a separate JAR in / lib/scala-library.jar. However, this JAR includes some code that is not supported by Android. Some code needs to be adjusted slightly, and some code must be removed. The custom build of scala-library.jar runs smoothly, at least for now. See Resources for the custom builds used here. We will call this JAR the Android library JAR.

With this JAR, the rest is easy. Just create an Android project using Eclipse's ADT plug-in. Then add a Scala feature (nature) to the project. Replace the standard Android library with the Scala library mentioned earlier. * add the output directory to the classpath. Now, we can begin. Now that we have the basic settings, let's take a look at the Android application we will create using Scala.

UnitsConverter

Now that we know how to use the Scala code to convert it into the binary format that will run on the Android device, we can use Scala to create a mobile application. The application we will create is a simple unit conversion application. This application allows you to easily switch back and forth between imperial and metric units. This is a very simple application, but we will see that even the simplest applications can benefit from using Scala. Let's first look at the layout elements of UnitsConverter.

Create a layout

You may be excited about writing Scala that runs on your phone, but not all mobile development programming should be done in Scala or Java. Android SDK provides a good way to separate user interface code from application logic using a XML-based layout system. Let's take a look at the main layout file for the application in this article, as shown in listing 1.

Listing 1. Main layout of the Converter application

< ?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>

The above code creates the main UI for the application very succinctly. Its root node is a RelativeLayout container element. There are many layout options in Android SDK. RelativeLayout instructs the runtime to use relative positioning to lay out different UI widgets. To use relative positioning, add a visible element-in this case, a TextView element. This is a simple element for displaying text. It is assigned an ID prompt_label. The next element, an EditText element (a text input box), will use it. This element has a layout_below attribute whose value is equal to prompt_label ID. In other words, EditText should be placed below the element named prompt_label.

The rest of the layout code is very simple. There is a tagged text input box, a tagged spinner (a combo box or drop-down box), a button, and a text box for output. Figure 2 shows a screenshot of the running application with different elements marked.

Figure 2. Android lLayout-decomposition diagram

So where do the different text values seen in the above view come from? Notice that some of the elements in listing 1 have a text attribute. For example, the prompt_label element has a text attribute equal to @ string/prompt_metric. This indicates that it will use a standard resource file in the Android application: the strings.xml file, as shown in listing 2.

Listing 2. Strings.xml resources

< ?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>

Now you can see where all the text in figure 2 comes from. The spinner has a drop-down box that contains units that can be used for measurement, which are not listed in listing 2. Instead, they come from another file, arrays.xml, as shown in listing 3.

Listing 3. Arrays.xml resources

< ?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>

Now we can see the values that will be used for the spinner. So how do these values appear in the spinner and how does the application switch between imperial and metric units? To answer these questions, we need to look at the application code itself.

Scala application code

The code for a Converter application is very simple-no matter what language it is written in. Of course, writing in Java is very easy, but writing in Scala is also not complicated. First, let's take a look at the code behind UI that we saw earlier.

The code behind the view

The easiest way to explain the Scala code that creates UI is to look at the code and then go through it. For any application, the default activity of the application is defined in the application's AndroidManifest.xml file. There is an Activity class behind any UI, and the default Activity defines the Activity class that executes when the application is first loaded. For an application as simple as this one, there is a Converter class whose source code is shown in listing 4.

Listing 4. Converter activity class

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)}}

Let's start at the top of this class. It extends android.app.Activity. This is a Java class, but the Java class can be easily subdivided from Scala. Next, it has some instance variables. Each instance variable corresponds to a UI element defined earlier. Note that each instance variable is also qualified to private [this]. This demonstrates an access control level unique to Scala that does not exist in the Java language. These variables are not only private, but only belong to specific instances of the Converter class. This level of access control is overkill for mobile applications, but if you are a Scala developer, you can safely use your familiar syntax on Android applications.

Going back to the code in listing 4, notice that we override the onCreate method. This is the method defined in the Activity class and is usually overridden by a custom Activity. If you write this code in the Java language, you should add an @ Override annotation. In Scala, override is a keyword used to ensure correctness. This prevents common errors such as misspelling method names. If the method name is misspelled, the Scala compiler will catch the method name and return an error. Note that there is no need to declare the return type on this method, as well as on any other method. The Scala compiler can easily infer this information, so there is no need to bother.

Most of the code in onCreate is similar to code written in the Java language. But there are a few interesting points. Notice that we use the findViewById method (defined in the Activity subclass) to get handles to different UI elements. This method is not type safe and requires type conversion (cast). In Scala, the parameterized method asInstanceOf [T] is used for type conversion, where T is the type to be converted. This transformation is functionally the same as the transformation in the Java language. But Scala has better syntax. Next, notice the call to setUomChoice (we'll talk about this method in more detail later). * notice that the above code gets a handle to the button created in the layout XML and adds a click event handler.

If you write in the Java language, you must pass in an implementation of the Android interface OnClickListener. This interface defines only one method: onClick. In fact, all you care about is that method, but you cannot pass in the method directly in the Java language. Unlike in Scala, you can pass in method literals (literal) or closures in Scala. Here, we use the syntax () = > {.} to represent the closure, where the body of the method is the content in curly braces. The opening / closing parentheses denote a function without arguments. However, I pass this closure to the setOnClickListener method on an instance of Button, which is a Java class defined in Android SDK. How do I pass Scala closures to Java API? Let's see.

Functional programming on Android

To understand how to get Android API to use function numeric quantities, take a look at the * * line defined by the Converter class. This is an important sentence. This is another good feature of Scala. You can import packages, classes, and so on anywhere in the code, and their scope is limited to the files in which they are imported. Here, we import everything in ConverterHelper. Listing 5 shows the ConverterHelper code.

Listing 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}}

This is a Scala singleton (singleton) because it uses object declarations instead of class declarations. The singleton pattern is built directly into Scala and can replace static methods or variables in the Java language. Here, this singleton holds a pair of functions: funcToClicker and funcToClicker0. These two functions take a function as an input parameter and return an instance of OnClickListener, an interface defined in Android SDK. For example, funcToClicker is defined to take a function f as an argument. The type of this function f is a function with an input parameter of type View (another class in Android) and returns Unit, which is the equivalent of void in Scala. It then returns an implementation of OnClickListener in which the interface's onClick method is implemented to apply the input function f to the View parameter. The other function, funcToClick0, does the same thing, except that it takes a function with no input parameters.

Both functions (funcToClicker and funcToClicker0) are defined as implicit functions (implicit). This is a convenient feature of Scala. It allows the compiler to implicitly convert one type to another. Here, when the compiler parses the onCreate method of the Converter class, it encounters a setOnClickListener call. This method requires an instance of OnClickListener. However, the compiler found a function. Before an error is reported and compilation fails, the compiler checks for the existence of an implicit function that allows the function to be converted to OnClickListener. Because there is such a function, it performs the transformation and compiles successfully. Now that we understand how to use closures in Android, let's take a closer look at the application logic-in particular, how to perform unit conversion calculations.

Unit conversion and calculation

Let's go back to listing 4. The function passed in to onClickListener receives the unit of measure and value entered by the user. It then creates an instance of Measurement and passes it to a UnitsConverter object. Listing 6 shows the corresponding code.

Listing 6. Measurement and 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 case 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 is a case class. This is a convenient feature in Scala. Decorating a class with "case" causes the class to generate a constructor that requires properties of the class, as well as implementations of equals, hashCode, and toString. It is ideal for data structure classes like Measurement. It also generates getter methods for the defined properties (in this case, uom and amount). You can also define those properties as vars (mutable variables), and then generate setter methods as well. Just a single line of Scala code can do so many things!

Next, UnitsConverter is also a singleton pattern because it is defined using the object keyword. It has only one convert method. Note that convert is defined as equivalent to a single statement-a match statement. It is a single expression, so no additional curly braces are required. It uses Scala's pattern matching. This is a powerful feature common in functional programming languages. It is similar to switch statements in the Java language and many other languages. However, we can match strings (in fact, there can be much more advanced matches than this). If the string matches, the appropriate calculation is performed and the formatted string is returned for display. *. Pay attention to the * case that matches _. Underscores are used as wildcards in many places in Scala. In this case, it means matching anything, which is similar to the default statement in the Java language.

Now that we understand the calculations in the application, * take a look at the remaining UI settings and menus.

UI initialization and menu

Go back to listing 4. We said we wanted to see setUomChoice. This method is defined with a parameter of type UnitsSystem. Let's take a look at how to define this type.

Listing 7. UnitsSystem

Sealed case class UnitsSystem () case object ENGLISH extends UnitsSystemcase object METRIC extends UnitsSystem

As we can see, UnitsSystem is a sealed case class with no attributes. It doesn't seem to be very useful. Next, let's look at two case objects. Remember, object stands for a singleton in Scala. Here, there are two case objects, each of which extends UnitsSystem. This is a common feature in Scala, which provides a simpler and more type-safe way to enumerate.

Now the implementation of setUomChoice is more reasonable. After getting a handle to the spinner, we match the type of UnitsSystem passed in. This identifies an array in the arrays.xml we saw earlier. This is to use the R class generated by Android SDK to represent resources, such as arrays.xml files. Once we know which array to use, we use that array as the data source for the spinner by creating an adapter to pass in the spinner (in this case, an ArrayAdapter).

* take a look at the onCreateOptionsMenu and onMenuItemSelected methods in listing 4. These methods are defined in Activity, and we will override them in the Converter activity. * methods to create a menu. The second method handles the event when the user selects English or metric from the menu. It calls setUomChoice again. This allows you to switch between converting from imperial units to metric units and from metric units to imperial units.

This is the end of the content of "what is the method of developing Scala+Eclipse+Android mobile phones". Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report