Hands-on lab given at #geecon for Visage Android development. A full VirtualBox image for running through the lab yourself is supplied here:
http://projavafx.com/VisageLab/
3. 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
4. Hello World Visage Stage { title: "Hello World" Scene { Text { "Hello World" } }} 4
5. Visage on Android 5 Visage Runs as a Native App on Android Full Access to all the Android APIs Declarative Layer on Top of Android APIs
7. 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
9. 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
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 11
12. Setting Up Your Machine Copy these files off the USB stick: VirtualBox for your platform (mac or windows) VisageLab folder Decompress VisageLab/Visage Dev2.vdi.zip Install VirtualBox Open Visage Dev.vbox 12
13. 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
14. Set Up Your Device for Debugging And mount it from: Devices > USB Devices > (your-device-name) 14 14
15. Or Create a Virtual Android Device 15 Launch the AVD Manager by typing: android
16. 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
18. 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
19. 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 20
21. 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
22. (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 23
24. Break the code (change in bold) public class HelloVisage extends Activity { @Override public void onCreate(Bundle savedIS) { super.onCreate(savedIS); Context context = getApplicationContext(); LinearLayoutlayout = null;//new LinearLayout(context); layout.setOrientation(LinearLayout.VERTICAL); TextView text = new TextView(context); text.setText("Hello World, HelloVisage"); layout.addView(text); setContentView(layout); } } 24
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 26
29. Add Some Properties… local.properties: visagehome=/home/visage/visage-sdk binary.extension= 29
30. Copy Over the Runtime JAR Copy: javafxrt.jar From: $visagehome/lib/shared/ To: $projectdir/libs 30
31. 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
33. Exercise 1.E – Simplified Visage Include the visage-android jar Modify the Visage code to use the new APIs Run on device/emulator 33
34. Copy the visage-android JAR Copy: visage-android.jar From: /home/visage/visage-android/dist/ To: $projectdir/libs 34
35. Android JavaFX Code public class HelloVisage extends Activity { override var view = LinearLayout { orientation: Orientation.VERTICAL view: TextView { text: "Hello World, Beautified Visage" } } } 35
36. 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
44. 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
49. 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
59. 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
60. Settings Class public class Settings extends PreferenceActivity { varusernamePref:EditTextPreference; varpasswordPref:EditTextPreference; varpollingPref:ListPreference; override var screen = PreferenceScreen { preferences: [ … 59
68. 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
69. 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
70. 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
71. 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
72. 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
73. 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
74. Getting Info from Sequences ints = [1, 3, 5, 7, 9] sizeofintsis 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]
75. 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]
76. 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: [] 75 1 3 5 7 9 [0] [1] [2] [3] [4]
79. 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 A: 0 2 A: [18] 3 A: 1
80. Module 3 EXTENDING VISAGE ANDROID APIs 79 Become a Visage contributor! Join me in the Hackergarten after the session
81. 80 Thank You Stephen Chin http://steveonjava.com/ Tweet: @steveonjava