Visage Android Hands-on Lab
-
Upload
stephen-chin -
Category
Technology
-
view
2.898 -
download
0
description
Transcript of Visage Android Hands-on Lab
The Visage Language
2
• Statically Compiled Language
• Based on F3 / JavaFX Script
• Planning Support for Different Platforms:–JavaFX 2.0
–Android
–Apache Pivot
–Flex
–JSF
> “Visage is a domain specific language (DSL) designed for the express purpose of writing user interfaces.”
Language Features• Declarative Object Construction
–Code looks like the UI it is representing.
• Data Binding–Variables can be bound to UI state, allowing automatic
updates and behavior to be triggered.
• Behavior Encapsulation–Visage provides closures to make it easy to
implement event handlers or other behavior-driven logic.
• Null Safety–Application logic will proceed even if intermediate
variables are undefined or null. 3
Hello World Visage
Stage { title: "Hello World" Scene { Text { "Hello World" } }}
4
Visage on Android
Visage Java Bytecode
Dalvik Bytecode
5
• Visage Runs as a Native App on Android
• Full Access to all the Android APIs
• Declarative Layer on Top of Android APIs
6
JAVA VS. VISAGE
Lesson 1
Language Similarities
Java is…• Statically typed
• Compiled to bytecodes
• Runs on the JVM
• Has a large library
Visage is…• Statically typed
• Compiled to bytecodes
• Runs on the JVM
• Can call Java libraries
7
Language Differences
8
Visage• Type Inferencing• Closures• Binding• Sequences• Animation Syntax
Java• Annotations• Generics• Multi-Threading
Integrating Visage and Java• Calling Java from Visage
–Can call Java interface or classes directly
–Automatic conversion to and from Arrays and Collections
–Can even extend Java interfaces and classes
• Calling Visage from Java–Easiest way is to create a Java interface that Visage
extends
–Can invoke Visage as a script and get results back
9
HELLO WORLD, VISAGE
Module 1
10
11
Exercise 1.A – Android Setup• Setup and run the VirtualBox image
• Create an emulator instance
• Create a new Android project from the command line
• Run the project in the emulator
Setting Up Your Machine
1. Copy these files off the USB stick:–VirtualBox for your platform (mac or windows)
–VisageLab folder
2. Decompress VisageLab/Visage Dev2.vdi.zip
3. Install VirtualBox
4. Open Visage Dev.vbox
12
Setting Up Your Machine• Download and Install the Android SDK
–http://developer.android.com/sdk/index.html
• Download the Visage SDK–http://code.google.com/p/visage/downloads/list
• Install the Android/Visage SDK–On the USB stick
13
Set Up Your Device for Debugging
• And mount it from:–Devices > USB Devices > (your-device-name)
1414
15
Or Create a Virtual Android Device
• Launch the AVD Manager by typing: android
Setting Up Your Project• Project creation command:
– android create project –t 1 –p HelloVisage –k org.test –a HelloVisage
• Arguments:–n : Project name (optional)
–t : Target ID of the new project (required)
–p : Project directory (required)
–k : Package name for the application (required)
–a : Name of the default Activity (required)
16
Android XML Code<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, HelloVisage"
/>
</LinearLayout>17
Plus some more Java…
public class HelloVisage extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedIS) {
super.onCreate(savedIS);
setContentView(R.layout.main);
}
}
18
Run Your Project• cd HelloVisage
• ant install
• Open it in the applications menu
19
20
Exercise 1.B – All Java Conversion• Make sure you have the basic project running
first
• Convert the XML Code to Java
• Run the all Java project
• You should get identical results
Converted XML Code (simplified)public class HelloVisage extends Activity {
@Override public void onCreate(Bundle savedIS) {
super.onCreate(savedIS);
Context context = getApplicationContext();
LinearLayout layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
TextView text = new TextView(context);
text.setText("Hello World, Java Only");
layout.addView(text);
setContentView(layout);
}
} 21
(and here are the imports…)
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
22
23
Exercise 1.C – DDMS Debugging• So you made a mistake in your code… the
compiler can’t catch everything–(even if you didn’t make a mistake, force one… a
beautiful NullPointerException will do)
• Launch DDMS and select your emulator/device
Break the code (change in bold)public class HelloVisage extends Activity {
@Override public void onCreate(Bundle savedIS) {
super.onCreate(savedIS);
Context context = getApplicationContext();
LinearLayout layout = null;//new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
TextView text = new TextView(context);
text.setText("Hello World, HelloVisage");
layout.addView(text);
setContentView(layout);
}
}24
DDMS Displaying a Stack Trace
25
26
Exercise 1.D – Visage Port• Modify the build script to compile Visage
• Copy the Visage Runtime libraries
• Convert the Java code to Visage
• Run on device/emulator
Modify the Build Script (1)<target name="-post-compile">
<path id="android.classpath">
<fileset dir="./libs" includes="*.jar" />
<path refid="android.target.classpath"/>
<pathelement location="${out.classes.absolute.dir}"/>
</path>
<pathconvert refid="android.classpath" property="androidcpath"/>
<path id="visage.sources">
<fileset dir="${source.absolute.dir}" includes="**/*.fx"/>
</path> 27
Modify the Build Script (2) <pathconvert refid="visage.sources" property="visagepath" pathsep=" "/>
<exec executable="${visagehome}/bin/javafxc${binary.extension}" failonerror="true" logerror="true">
<arg value="-d"/>
<arg value="${out.classes.absolute.dir}"/>
<arg value="-cp"/>
<arg value="${androidcpath}"/>
<arg line="${visagepath}"/>
</exec>
</target> 28
Add Some Properties…• local.properties:
–visagehome=/home/visage/visage-sdk
–binary.extension=
29
Copy Over the Runtime JAR• Copy:
–javafxrt.jar
• From:–$visagehome/lib/shared/
• To:–$projectdir/libs
30
Straight JavaFX Conversion...public class Test extends Activity {
override function onCreate(savedInstanceState:Bundle) {
super.onCreate(savedInstanceState);
def context = getApplicationContext();
def layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
def text = new TextView(context);
text.setText("Hello World, Hello Long Visage");
layout.addView(text);
setContentView(layout);
}
}31
Rename your source file• *.java -> *.fx
32
Exercise 1.E – Simplified Visage• Include the visage-android jar
• Modify the Visage code to use the new APIs
• Run on device/emulator
33
Copy the visage-android JAR• Copy:
visage-android.jar
• From:/home/visage/visage-android/dist/
• To:$projectdir/libs
34
Android JavaFX Code
public class HelloVisage extends Activity {
override var view = LinearLayout {
orientation: Orientation.VERTICAL
view: TextView {
text: "Hello World, Beautified Visage"
}
}
}
35
And change the imports…• org.visage.android.app.Activity;
• org.visage.android.widget.LinearLayout;
• org.visage.android.widget.Orientation;
• org.visage.android.widget.TextView;
36
Working Hello Visage Application
37
VISAGE LANGUAGE FUNDAMENTALS
Lesson 2
38
Datatype SupportDataType Java Equivalent Range Examples
Boolean boolean true or false true, false
Integer int -2147483648 to 2147483647 2009, 03731, 0x07d9
Number Float 1.40×10-45 and 3.40×1038 3.14, 3e8, 1.380E-23
String String N/A "java's", 'in"side"er'
Duration <None> -263 to 263-1 milliseconds 1h, 5m, 30s, 500ms
Length <None> dp, sp, em, %, mm, cm, in 2mm, 5sp, 1in
Angle <None> rad, deg, turn 1rad, 30deg
Color <None> #RRGGBB, #RGB,#RRGGBB|AA, #RGB|A
#CCCCCC, #202020|D0
Character char 0 to 65535 0, 20, 32
Byte byte -128 to 127 -5, 0, 5
Short short -32768 to 32767 -300, 0, 521
Long long -263 to 263-1 2009, 03731, 0x07d9
Float float 1.40×10-45 and 3.40×1038 3.14, 3e8, 1.380E-23
Double double 4.94×10-324 and 1.80×10308 3.14, 3e231, 1.380E-12339
Visage Operators
Operator Meaning Precedence Examples ++ Pre/post increment 1 ++i, i++ -- Pre/post decrement 1 --i, i-- not Boolean negation 2 not (cond) * Multiply 3 2 * 5, 1h * 4 / Divide 3 9 / 3, 1m / 3 mod Modulo 3 20 mod 3 + Add 4 0 + 2, 1m + 20s - Subtract (or negate) 4 (2) -2, 32 -3, 1h -5m
40
> Multiplication and division of two durations is allowed, but not meaningful> Underflows/Overflows will fail silently, producing inaccurate results> Divide by zero will throw a runtime exception
Visage Operators (continued)
Operator Meaning Precedence Examples == Equal 5 value1 == value2, 4 == 4 != Not equal 5 value1 != value2, 5 != 4 < Lessthan 5 value1 < value2, 4 < 5 <= Lessthanorequal 5 value1 <= value2, 5 <= 5 > Greater than 5 value1 > value2, 6 > 5 >= Greater than or equal 5 value1 >= value2, 6 >= 6 instanceof Is instance of class 6 node instanceof Text as Typecast to class 6 node as Text and Boolean and 7 cond1 and cond2 or Boolean or 8 cond1 or cond2 += Add and assign 9 value += 5 -= Subtract and assign 9 value -= 3 *= Multiply and assign 9 value *= 2 /= Divide and assign 9 value /=4 = Assign 9 value = 7
41
Access Modifiers
Modifier Name Description<default> Script only access Only accessible within the same script file
package Package access Only accessible within the same package
protected Protected access Only accessible within the same package or by subclasses.
public Public access Can be accessed anywhere.
public-read Read access modifier Var/def modifier to allow a variable to be read anywhere
public-init Init access modifier Var/def modifier to allow a variable to be initialized or read anywhere
42
Data Binding• A variable or a constant can be bound to an
expression–var x = bind a + b;
• The bound expression is remembered
• The dependencies of the expression is watched
• Variable is updated lazily when possible
43
CONTROLS AND SETTINGS
Module 2
44
Exercise 2.A – NetBeans Integration
• Create a new JavaFX NetBeans project
• Merge in build scripts from Android project
• Start coding!
45
Create a new JavaFX Project• File > New Project…
• Name the project “ConfigReporter”
• In package "org.test"
46
Merging Project Folders• Copy these files over:
–*.properties
–AndroidManifest.xml
–res/
–libs/
–proguard.cfg
–build.xml [replace]
47
Merging Build Scripts• Update the build.xml file:
Set the project name to “ConfigReporter”
• Update the strings.xml file:Set the app_name to “ConfigReporter”
• Load the NetBeans property files (in build.xml):<property file="nbproject/private/config.properties"/>
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
<property file="${user.properties.file}"/>
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>48
Alias NetBeans Targets:<target name="launch" depends="install”>
<exec executable="${adb}" failonerror="true">
<arg line="${adb.device.arg}"/>
<arg value="shell"/>
<arg value="am"/>
<arg value="start"/>
<arg value="-n"/>
<arg value=”org.test/.ConfigReporter"/>
<arg value="-a"/>
<arg value="android.intent.action.MAIN"/>
</exec>
</target>
<target name="jar" depends="compile"/>
<target name="run" depends="launch"/>49
Update AndroidManifest.xml• Change project name to "ConfigReporter"
50
Modify Project Properties• Set JavaFX Platform to “Visage_SDK”
• Add Libraries:–“libs” folder
–android.jar
51
Update ConfigReporter.fx• Make it extend the visage Activity class
• For now, you can copy the logic from HelloVisage
52
Exercise 2.C – Android Controls• Create a Text Field
• Create an Edit Box
• Wire them up using Binding
53
Bound Controls (1)
override var view = LinearLayout {
orientation: Orientation.VERTICAL
var secret:String;
view: [
EditText {
hint: "Super Secret Text”
password: true
text: bind secret with inverse
54
Bound Controls (2)
}
TextView {
text: "Is Revealed!!!”
}
TextView {
text: bind secret
}
]
}55
Exercise 2.D – Button Handler• Create a Button Control
• Add an onClick handler
• Make something happen (maybe a bind)
56
Button onClick handlerButton {
text: "Launch Settings"
onClick: function() {
startActivity(new Intent(this, Settings.class));
setting = "Launching...";
}
}
TextView {
text: "Setting is:"
}
TextView {
text: bind setting
}57
Exercise 2.E – Android Settings• Create a Settings Activity
• Populate it with the following preferences:–Text
–Password
–List
• Launch it from the Button control
58
Settings Class
public class Settings extends PreferenceActivity {
var usernamePref:EditTextPreference;
var passwordPref:EditTextPreference;
var pollingPref:ListPreference;
override var screen = PreferenceScreen {
preferences: [
…
59
Text Preference
PreferenceCategory {
title: "Preferences"
preferences: [
usernamePref = EditTextPreference {
title: "Username"
key: "usernamePref"
summary: bind if (usernamePref.text == "") "Currently undefined" else "Current value: {usernamePref.text}"
} 60
Password Preference
passwordPref = EditTextPreference {
title: "Password”
key: "passwordPref”
summary: bind passwordPref.text.replaceAll(".", "*");
}
61
List Preference
pollingPref = ListPreference {
title: "Polling Interval"
key: "pollingPref"
defaultValue: "60000"
entries: ["30 seconds", "1 minute", "5 minutes", "10 minutes", "15 minutes", "30 minutes", "1 hour"]
entryValues: ["30000", "60000", "300000", "600000", "900000", "1800000", "3600000"]
summary: bind pollingPref.entry
}62
Service Metadata• Update AndroidManifest.xml:
<activity android:name=".Settings" android:label="@string/settings_label"/>
• Update string.xml:<string name="settings_label">Settings</string>
63
Invoke the new service• In the onClick handler:
startActivity(new Intent(this, Settings.class));
64
Working Settings Panel
65
ADVANCED JAVAFX SEQUENCES
Lesson 3
66
What Bind Updates
var x = bind if(a) then b else c• x is updated if a or b or c changes
var x = bind for (i in [a..b]) { i * i }• Not everything is recalculated
• If a = 1 and b = 2, x is [1, 4]• If b changes to 3, only the added element is
calculated
67
1 4 9
Binding to Expressions• Binding to a block
• Bound block may contain any number of defs followed by one expression
• Dependencies of block is backtraced from the expression
• Binding to function invocation expression–Regular function: dependencies are parameters
–Bound function: backtraced from final expression inside function
68
Binding to Object Literals
var a = 3; var b = 4;var p = bind Point { x: a, y: b };var q = bind Point { x: bind a, y: b };var r = bind Point { x: bind a, y: bind b };
• When a changes:–p gets a new instance of Point
–q and r keep the old instance with a new x value
–r will never get a new instance of Point• (the outer bind in r is useless)
69
Visage Sequences• Represents collections of homogeneous data
• A fundamental container data type
• Rich set of language facilities
• Contributor to declarative syntax
• Automatic conversion to and from Java Arrays and Collections
70
Creating Sequences• Explicit sequence expression
–[1, 3, 5, 7, 9]
• Elements are separated by commas
• Comma may be omitted if element ends with brace
71
1 3 5 7 9
Creating Sequences• Numeric sequence with range expressions:
–[1..10]
• Can have a step:–[1..10 step 2]
–[0.0..0.9 step 0.1]
• Can be decreasing:–[10..1 step -3]
• Beware of step that goes opposite direction:–[10..1] is []
• Exclusive right end–[1..<5]
72
1 2 3 4 5 6 7 8 9 10
1 3 5 7 9
0 .1 .2 .3 .4 .5 .6 .7 .8 .9
10 7 4 1
1 2 3 4
Getting Info from Sequencesints = [1, 3, 5, 7, 9]
• sizeof ints is 5• ints[0] is 1, ints[1] is 3, ..., ints[4] is 9• ints[-1] is 0 (default value of Integer), so is ints[5]
• For a sequence of objects, the default is null
73
1 3 5 7 9
[0] [1] [2] [3] [4]
Getting Slices from Sequences
ints = [1, 3, 5, 7, 9]
• ints[0..2] is [1, 3, 5]• ints[0..<2] is [1, 3]• ints[2..] is [5, 7, 9]• ints[2..<] is [5, 7]• ints[2..0], ints[-2..-1], ints[5..6] are all []s
74
1 3 5 7 9
[0] [1] [2] [3] [4]
Getting Subsets from Sequences
ints = [1, 3, 5, 7, 9]
• ints[k | k > 6] is:–[7, 9] (k > 6 is a condition)
• ints[k | indexof k < 2] is:–[1, 3]
• ints[k | k > 10] is:–[] 7
5
1 3 5 7 9
[0] [1] [2] [3] [4]
Inserting into Sequencesints = [1, 3, 5, 7, 9]
insert 20 into ints
insert 30 before ints[2]
insert 40 after ints[4]
insert [50, 60] into ints
76
1 3 5 7 9
1 3 5 7 9
1 3 5 7 9
20
2030
1 3 5 7 9 2030 40
1 3 5 7 9 2030 40 50 60
Deleting from Sequences• ints = [1, 3, 5, 7, 9]
• delete 7 from ints
• delete ints[0]
• delete ints[0..1]
• delete ints: ints becomes []
1 3 5 7 9
1 3 5 9
3 5 9
9
1 3 5 7 9
Sequence Puzzlers
What is the size of this sequence:
• [1..10 step -1]
What does this evaluate to:
• [10..<20 step 2][k|k>17]
What is the size of this sequence:
• sizeof [20..1 step -3]
78
1
2
3
A: 0
A: 1
A: [18]
EXTENDING VISAGE ANDROID APIS
Module 3
79
Become a Visage contributor!
Join me in the Hackergartenafter the session