Visage Android Hands-on Lab


Published on

Hands-on lab given at #geecon for Visage Android development. A full VirtualBox image for running through the lab yourself is supplied here:

Published in: Technology, Education
  • Now able to download the proper image file, thank you.
    Are you sure you want to  Yes  No
    Your message goes here
  • Sorry about that. I am uploading a new copy of the image now.
    Are you sure you want to  Yes  No
    Your message goes here
  • The VirtualBox image looks like it might be corrupt: (0 bytes reported by Firefox)

    Is there an alternative way to get the VirtualBox image? If not then is there a place where I can get Already I have the following software installed on my Ubuntu 10.04 PC:

    - Visage compiler built from the mercurial sources (includes the new data types)
    - NB 6.9 (with JavaFX plugin)
    - Eclipse 3.6 (with ADK plugin)
    - Android SDK (for Android 2.2)
    Are you sure you want to  Yes  No
    Your message goes here
  • Visage is 0byte
    Are you sure you want to  Yes  No
    Your message goes here
  • Can't figure out which one need to be dowloaded or ?
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Visage Android Hands-on Lab

  1. 1. Visage Android Hands-on Lab<br />Stephen Chin – GXS<br /><br />
  2. 2. The Visage Language<br />2<br /><ul><li>“Visage is a domain specific language (DSL) designed for the express purpose of writing user interfaces.”</li></ul>Statically Compiled Language<br />Based on F3 / JavaFX Script<br />Planning Support for Different Platforms:<br />JavaFX 2.0<br />Android<br />Apache Pivot<br />Flex<br />JSF<br />
  3. 3. Language Features<br />Declarative Object Construction<br />Code looks like the UI it is representing. <br />Data Binding<br />Variables can be bound to UI state, allowing automatic updates and behavior to be triggered. <br />Behavior Encapsulation<br />Visage provides closures to make it easy to implement event handlers or other behavior-driven logic. <br />Null Safety<br />Application logic will proceed even if intermediate variables are undefined or null. <br />3<br />
  4. 4. Hello World Visage<br />Stage {  title: "Hello World"  Scene {    Text {      "Hello World"    }  }}<br />4<br />
  5. 5. Visage on Android<br />5<br />Visage Runs as a Native App on Android<br />Full Access to all the Android APIs<br />Declarative Layer on Top of Android APIs<br />
  6. 6. 6<br />Lesson 1<br />Java vs. visage<br />
  7. 7. Language Similarities<br />Java is…<br />Statically typed<br />Compiled to bytecodes<br />Runs on the JVM<br />Has a large library<br />Visage is…<br />Statically typed<br />Compiled to bytecodes<br />Runs on the JVM<br />Can call Java libraries<br />7<br />
  8. 8. Language Differences<br />8<br />
  9. 9. Integrating Visage and Java<br />Calling Java from Visage<br />Can call Java interface or classes directly<br />Automatic conversion to and from Arrays and Collections<br />Can even extend Java interfaces and classes<br />Calling Visage from Java<br />Easiest way is to create a Java interface that Visage extends<br />Can invoke Visage as a script and get results back<br />9<br />
  10. 10. Hello World, Visage<br />Module 1<br />10<br />
  11. 11. Exercise 1.A – Android Setup<br />Setup and run the VirtualBox image<br />Create an emulator instance<br />Create a new Android project from the command line<br />Run the project in the emulator<br />11<br />
  12. 12. Setting Up Your Machine<br />Copy these files off the USB stick:<br />VirtualBox for your platform (mac or windows)<br />VisageLab folder<br />Decompress VisageLab/Visage<br />Install VirtualBox<br />Open Visage Dev.vbox<br />12<br />
  13. 13. Setting Up Your Machine<br />Download and Install the Android SDK<br /><br />Download the Visage SDK<br /><br />Install the Android/Visage SDK<br />On the USB stick<br />13<br />
  14. 14. Set Up Your Device for Debugging<br />And mount it from:<br />Devices > USB Devices > (your-device-name)<br />14<br />14<br />
  15. 15. Or Create a Virtual Android Device<br />15<br />Launch the AVD Manager by typing: android<br />
  16. 16. Setting Up Your Project<br />Project creation command:<br />android create project –t 1 –p HelloVisage –k org.test –a HelloVisage<br />Arguments:<br />n : Project name (optional)<br />t : Target ID of the new project (required)<br />p : Project directory (required)<br />k : Package name for the application (required)<br />a : Name of the default Activity (required)<br />16<br />
  17. 17. Android XML Code<br /><?xml version="1.0" encoding="utf-8"?><br /><LinearLayoutxmlns:android="" <br />android:orientation="vertical" <br />android:layout_width="fill_parent" <br />android:layout_height="fill_parent"<br /> ><br /><TextView<br />android:layout_width="fill_parent"<br />android:layout_height="wrap_content"<br />android:text="Hello World, HelloVisage"<br />/><br /></LinearLayout><br />17<br />
  18. 18. Plus some more Java…<br />public class HelloVisage extends Activity {<br />/** Called when the activity is first created. */<br />@Override<br />public void onCreate(Bundle savedIS) {<br />super.onCreate(savedIS);<br />setContentView(R.layout.main);<br /> }<br />}<br />18<br />
  19. 19. Run Your Project<br />cd HelloVisage<br />ant install<br />Open it in the applications menu<br />19<br />
  20. 20. Exercise 1.B – All Java Conversion<br />Make sure you have the basic project running first<br />Convert the XML Code to Java<br />Run the all Java project<br />You should get identical results<br />20<br />
  21. 21. Converted XML Code (simplified)<br />public class HelloVisage extends Activity {<br /> @Override public void onCreate(Bundle savedIS) {<br />super.onCreate(savedIS);<br />Context context = getApplicationContext();<br />LinearLayout layout = new LinearLayout(context);<br />layout.setOrientation(LinearLayout.VERTICAL);<br />TextView text = new TextView(context);<br />text.setText("Hello World, Java Only");<br />layout.addView(text);<br />setContentView(layout);<br />}<br />}<br />21<br />
  22. 22. (and here are the imports…)<br />import;<br />import android.content.Context;<br />import android.os.Bundle;<br />import android.widget.LinearLayout;<br />import android.widget.TextView;<br />22<br />
  23. 23. Exercise 1.C – DDMS Debugging<br />So you made a mistake in your code… the compiler can’t catch everything<br />(even if you didn’t make a mistake, force one… a beautiful NullPointerException will do)<br />Launch DDMS and select your emulator/device<br />23<br />
  24. 24. Break the code (change in bold)<br />public class HelloVisage extends Activity {<br /> @Override public void onCreate(Bundle savedIS) {<br />super.onCreate(savedIS);<br />Context context = getApplicationContext();<br />LinearLayoutlayout = null;//new LinearLayout(context);<br />layout.setOrientation(LinearLayout.VERTICAL);<br />TextView text = new TextView(context);<br />text.setText("Hello World, HelloVisage");<br />layout.addView(text);<br />setContentView(layout);<br />}<br />}<br />24<br />
  25. 25. DDMS Displaying a Stack Trace<br />25<br />
  26. 26. Exercise 1.D – Visage Port<br />Modify the build script to compile Visage<br />Copy the Visage Runtime libraries<br />Convert the Java code to Visage<br />Run on device/emulator<br />26<br />
  27. 27. Modify the Build Script (1)<br /><target name="-post-compile"><br /> <path id="android.classpath"><br /> <filesetdir="./libs" includes="*.jar" /><br /> <path refid=""/><br /> <pathelement location="${out.classes.absolute.dir}"/><br /> </path><br /> <pathconvertrefid="android.classpath" property="androidcpath"/><br /> <path id="visage.sources"><br /> <filesetdir="${source.absolute.dir}" includes="**/*.fx"/><br /> </path><br />27<br />
  28. 28. Modify the Build Script (2)<br /> <pathconvertrefid="visage.sources" property="visagepath" pathsep=" "/><br /> <exec executable="${visagehome}/bin/javafxc${binary.extension}" failonerror="true" logerror="true"><br /> <arg value="-d"/><br /> <arg value="${out.classes.absolute.dir}"/><br /> <arg value="-cp"/><br /> <arg value="${androidcpath}"/><br /> <arg line="${visagepath}"/><br /> </exec><br /></target><br />28<br />
  29. 29. Add Some Properties…<br /><br />visagehome=/home/visage/visage-sdk<br />binary.extension=<br />29<br />
  30. 30. Copy Over the Runtime JAR<br />Copy:<br />javafxrt.jar<br />From:<br />$visagehome/lib/shared/<br />To:<br />$projectdir/libs<br />30<br />
  31. 31. Straight JavaFX Conversion...<br />public class Test extends Activity {<br /> override function onCreate(savedInstanceState:Bundle) {<br />super.onCreate(savedInstanceState);<br />def context = getApplicationContext();<br />def layout = new LinearLayout(context);<br />layout.setOrientation(LinearLayout.VERTICAL);<br />def text = new TextView(context);<br />text.setText("Hello World, Hello Long Visage");<br />layout.addView(text);<br />setContentView(layout);<br />}<br />}<br />31<br />
  32. 32. Rename your source file<br />*.java -> *.fx<br />32<br />
  33. 33. Exercise 1.E – Simplified Visage<br />Include the visage-android jar<br />Modify the Visage code to use the new APIs<br />Run on device/emulator<br />33<br />
  34. 34. Copy the visage-android JAR<br />Copy:<br />visage-android.jar<br />From:<br />/home/visage/visage-android/dist/<br />To:<br />$projectdir/libs<br />34<br />
  35. 35. Android JavaFX Code<br />public class HelloVisage extends Activity {<br /> override var view = LinearLayout {<br /> orientation: Orientation.VERTICAL<br /> view: TextView {<br /> text: "Hello World, Beautified Visage"<br /> }<br /> }<br />}<br />35<br />
  36. 36. And change the imports…<br />;<br />;<br />;<br />;<br />36<br />
  37. 37. Working Hello Visage Application<br />37<br />
  38. 38. Visage Language Fundamentals<br />Lesson 2<br />38<br />
  39. 39. Datatype Support<br />39<br />
  40. 40. Visage Operators<br />40<br /><ul><li>Multiplication and division of two durations is allowed, but not meaningful
  41. 41. Underflows/Overflows will fail silently, producing inaccurate results
  42. 42. Divide by zero will throw a runtime exception</li></li></ul><li>Visage Operators (continued)<br />41<br />
  43. 43. Access Modifiers<br />42<br />
  44. 44. Data Binding<br />A variable or a constant can be bound to an expression<br />var x = bind a + b;<br />The bound expression is remembered<br />The dependencies of the expression is watched<br />Variable is updated lazily when possible<br />43<br />
  45. 45. CONTROLS AND SETTINGS<br />Module 2<br />44<br />
  46. 46. Exercise 2.A – NetBeans Integration<br />Create a new JavaFXNetBeans project<br />Merge in build scripts from Android project<br />Start coding!<br />45<br />
  47. 47. Create a new JavaFX Project<br />File > New Project…<br />Name the project “ConfigReporter”<br />In package "org.test"<br />46<br />
  48. 48. Merging Project Folders<br />Copy these files over:<br />*.properties<br />AndroidManifest.xml<br />res/<br />libs/<br />proguard.cfg<br />build.xml [replace]<br />47<br />
  49. 49. Merging Build Scripts<br />Update the build.xml file:<br />Set the project name to “ConfigReporter”<br />Update the strings.xml file:<br />Set the app_name to “ConfigReporter”<br />Load the NetBeans property files (in build.xml):<br /><property file="nbproject/private/"/><br /><property file="nbproject/private/configs/${config}.properties"/><br /><property file="nbproject/private/"/><br /><property file="${}"/><br /><property file="nbproject/configs/${config}.properties"/><br /><property file="nbproject/"/><br />48<br />
  50. 50. Alias NetBeans Targets:<br /><target name="launch" depends="install”><br /> <exec executable="${adb}" failonerror="true"><br /> <arg line="${adb.device.arg}"/><br /> <arg value="shell"/><br /> <arg value="am"/><br /> <arg value="start"/><br /> <arg value="-n"/><br /> <arg value=”org.test/.ConfigReporter"/><br /> <arg value="-a"/><br /> <arg value="android.intent.action.MAIN"/><br /> </exec><br /></target><br /><target name="jar" depends="compile"/><br /><target name="run" depends="launch"/><br />49<br />
  51. 51. Update AndroidManifest.xml<br />Change project name to "ConfigReporter"<br />50<br />
  52. 52. Modify Project Properties<br />Set JavaFX Platform to “Visage_SDK”<br />Add Libraries:<br />“libs” folder<br />android.jar<br />51<br />
  53. 53. Update ConfigReporter.fx<br />Make it extend the visage Activity class<br />For now, you can copy the logic from HelloVisage<br />52<br />
  54. 54. Exercise 2.C – Android Controls<br />Create a Text Field<br />Create an Edit Box<br />Wire them up using Binding<br />53<br />
  55. 55. Bound Controls (1)<br />override var view = LinearLayout {<br />orientation: Orientation.VERTICAL<br />varsecret:String;<br />view: [<br />EditText {<br />hint: "Super Secret Text”<br />password: true<br />text: bind secret with inverse<br />54<br />
  56. 56. Bound Controls (2)<br />}<br />TextView {<br />text: "Is Revealed!!!”<br />}<br />TextView {<br />text: bind secret<br />}<br />]<br />}<br />55<br />
  57. 57. Exercise 2.D – Button Handler<br />Create a Button Control<br />Add an onClick handler<br />Make something happen (maybe a bind)<br />56<br />
  58. 58. Button onClick handler<br />Button {<br /> text: "Launch Settings"<br />onClick: function() {<br />startActivity(new Intent(this, Settings.class));<br /> setting = "Launching...";<br /> }<br />}<br />TextView {<br /> text: "Setting is:"<br />}<br />TextView {<br /> text: bind setting<br />}<br />57<br />
  59. 59. Exercise 2.E – Android Settings<br />Create a Settings Activity<br />Populate it with the following preferences:<br />Text<br />Password<br />List<br />Launch it from the Button control<br />58<br />
  60. 60. Settings Class<br />public class Settings extends PreferenceActivity {<br />varusernamePref:EditTextPreference;<br />varpasswordPref:EditTextPreference;<br />varpollingPref:ListPreference;<br /> override var screen = PreferenceScreen {<br /> preferences: [<br /> …<br />59<br />
  61. 61. Text Preference<br />PreferenceCategory {<br /> title: "Preferences"<br /> preferences: [<br />usernamePref = EditTextPreference {<br /> title: "Username"<br /> key: "usernamePref"<br /> summary: bind if (usernamePref.text == "") "Currently undefined" else "Current value: {usernamePref.text}"<br />}<br />60<br />
  62. 62. Password Preference<br />passwordPref = EditTextPreference {<br /> title: "Password”<br /> key: "passwordPref”<br /> summary: bind passwordPref.text.replaceAll(".", "*");<br />}<br />61<br />
  63. 63. List Preference<br />pollingPref= ListPreference {<br /> title: "Polling Interval"<br />key: "pollingPref"<br />defaultValue: "60000"<br />entries: ["30 seconds", "1 minute", "5 minutes", "10 minutes", "15 minutes", "30 minutes", "1 hour"]<br />entryValues: ["30000", "60000", "300000", "600000", "900000", "1800000", "3600000"]<br />summary: bind pollingPref.entry<br />}<br />62<br />
  64. 64. Service Metadata<br />Update AndroidManifest.xml:<br /><activity android:name=".Settings" android:label="@string/settings_label"/><br />Update string.xml:<br /><string name="settings_label">Settings</string><br />63<br />
  65. 65. Invoke the new service<br />In the onClick handler:<br />startActivity(new Intent(this, Settings.class));<br />64<br />
  66. 66. Working Settings Panel<br />65<br />
  67. 67. Advanced Javafx sequences<br />Lesson 3<br />66<br />
  68. 68. What Bind Updates<br />var x = bind if(a) then b else c<br />x is updated if a or b or c changes<br />var x = bind for (i in [a..b]) { i * i }<br />Not everything is recalculated<br />If a = 1 and b = 2, x is [1, 4]<br />If b changes to 3, only the added element is calculated<br />67<br />1<br />4<br />9<br />
  69. 69. Binding to Expressions<br />Binding to a block<br />Bound block may contain any number of defs followed by one expression<br />Dependencies of block is backtraced from the expression<br />Binding to function invocation expression<br />Regular function: dependencies are parameters<br />Bound function: backtraced from final expression inside function<br />68<br />
  70. 70. Binding to Object Literals<br />var a = 3; var b = 4;<br />var p = bind Point { x: a, y: b };<br />var q = bind Point { x: bind a, y: b };<br />var r = bind Point { x: bind a, y: bind b };<br />When a changes:<br />p gets a new instance of Point<br />q and r keep the old instance with a new x value<br />r will never get a new instance of Point<br />(the outer bind in r is useless)<br />69<br />
  71. 71. Visage Sequences<br />Represents collections of homogeneous data<br />A fundamental container data type<br />Rich set of language facilities<br />Contributor to declarative syntax<br />Automatic conversion to and from Java Arrays and Collections<br />70<br />
  72. 72. Creating Sequences<br />Explicit sequence expression<br />[1, 3, 5, 7, 9]<br />Elements are separated by commas<br />Comma may be omitted if element ends with brace<br />71<br />1<br />3<br />5<br />7<br />9<br />
  73. 73. Creating Sequences<br />Numeric sequence with range expressions:<br />[1..10]<br />Can have a step:<br />[1..10 step 2]<br />[0.0..0.9 step 0.1]<br />Can be decreasing:<br />[10..1 step -3]<br />Beware of step that goes opposite direction:<br />[10..1] is []<br />Exclusive right end<br />[1..<5]<br />72<br />1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />1<br />3<br />5<br />7<br />9<br />0<br />.1<br />.2<br />.3<br />.4<br />.5<br />.6<br />.7<br />.8<br />.9<br />10<br />7<br />4<br />1<br />1<br />2<br />3<br />4<br />
  74. 74. Getting Info from Sequences<br />ints = [1, 3, 5, 7, 9]<br />sizeofintsis 5<br />ints[0] is 1, ints[1] is 3, ..., ints[4] is 9<br />ints[-1] is 0 (default value of Integer), so is ints[5]<br />For a sequence of objects, the default is null<br />73<br />1<br />3<br />5<br />7<br />9<br />[0]<br />[1]<br />[2]<br />[3]<br />[4]<br />
  75. 75. Getting Slices from Sequences<br />ints = [1, 3, 5, 7, 9]<br />ints[0..2] is [1, 3, 5]<br />ints[0..<2] is [1, 3]<br />ints[2..] is [5, 7, 9]<br />ints[2..<] is [5, 7]<br />ints[2..0], ints[-2..-1], ints[5..6] are all []s<br />74<br />1<br />3<br />5<br />7<br />9<br />[0]<br />[1]<br />[2]<br />[3]<br />[4]<br />
  76. 76. Getting Subsets from Sequences<br />ints = [1, 3, 5, 7, 9]<br />ints[k | k > 6] is:<br />[7, 9] (k > 6 is a condition)<br />ints[k | indexof k < 2] is:<br />[1, 3]<br />ints[k | k > 10] is:<br />[]<br />75<br />1<br />3<br />5<br />7<br />9<br />[0]<br />[1]<br />[2]<br />[3]<br />[4]<br />
  77. 77. Inserting into Sequences<br />ints = [1, 3, 5, 7, 9]<br />insert 20 into ints<br />insert 30 before ints[2]<br />insert 40 after ints[4]<br />insert [50, 60] into ints<br />1<br />3<br />5<br />7<br />9<br />1<br />3<br />5<br />7<br />9<br />20<br />1<br />3<br />5<br />7<br />9<br />20<br />30<br />1<br />3<br />5<br />7<br />9<br />20<br />30<br />40<br />1<br />3<br />5<br />7<br />9<br />20<br />30<br />40<br />50<br />60<br />76<br />
  78. 78. Deleting from Sequences<br />ints = [1, 3, 5, 7, 9]<br />delete 7 from ints<br />delete ints[0]<br />delete ints[0..1]<br />delete ints: ints becomes []<br />1<br />3<br />5<br />7<br />9<br />1<br />3<br />5<br />7<br />9<br />1<br />3<br />5<br />9<br />3<br />5<br />9<br />9<br />
  79. 79. Sequence Puzzlers<br />What is the size of this sequence:<br />[1..10 step -1]<br />What does this evaluate to:<br />[10..<20 step 2][k|k>17]<br />What is the size of this sequence:<br />sizeof [20..1 step -3]<br />78<br />1<br />A: 0<br />2<br />A: [18]<br />3<br />A: 1<br />
  80. 80. Module 3<br />EXTENDING VISAGE ANDROID APIs<br />79<br />Become a Visage contributor!<br />Join me in the Hackergarten<br />after the session<br />
  81. 81. 80<br />Thank You<br />Stephen Chin<br /><br />Tweet: @steveonjava<br />