Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Migrating apps from Android to HTML5 with GWT


Alberto Alonso Ruibal
DevFest-X BCN, November 2012

Who am I?

Apps:

We have some Android Apps


And we want them in HTML5

HTML5 is a great platform... for Desktops:

But we have lots of Java code

GWT is a magic toolbox that compiles Java to Javascript, and also: And GWT is mature

GWT API

GWT maps directly the JS features
JAVA (GWT)
JSNI *
HTML5 + JS
* Javascript Native Interface:
public native void alert(String message) /*-{
		// Here goes the Javascript Code
		alert(message);
}-*/;

Where are my APIs?

But GWT lacks a LOT of standard Java APIs: JRE Emulation isn't complete
JRE emulation doc

Development Tools

Eclipse
  • Eclipse Plugin: ADT
  • Android SDK
  • Google Plugin for Eclipse
  • Google Web Toolkit SDK
  • GWT Designer, Speed Tracer
With our favourite features: Code assist, debugger, refactor...

App Structure

Activities
  • Extends class Activity
  • Methods: onCreate(), onResume(), onPause(), OnDestroy()
  • Intents for navigation
Modules
  • Extends class EntryPoint
  • Method: onModuleLoad()
  • Navigation replacing root panel content

App Manifest

AndroidManifest.xml
  • Defines activities, permissions, intents...
<module_name>.gwt.xml
  • Defines EntryPoint and the source loc.
  • Also defines inherits (other modules)
<module rename-to="chess">
  <inherits name="com.google.gwt.user.User"/>
  <inherits name="com.google.gwt.user.theme.clean.Clean"/>
  
  <inherits name="com.mobialia.gwt.androidemu" />

  <entry-point class="com.mobialia.chess.Chess"/>
  <source path="chess"/>

Resources

  • Resources selector with modifiers
  • Languages, DPIs, screen size
  • Maps automagically all the resources to the R class
  • ClientBundle for images, css, etc.
  • Constants for strings and i18n
  • You need to create classes manually with one method for each String/Image...

Multithreading

  • Standard Java Threads
  • Also AsyncTasks
  • You cannot modify the interface outside the main thread
Web Workers
  • Separated GWT module
  • Messaging
  • You can access the DOM only from the main Javascript Thread

Messaging

Handlers and Messages
  • Handler.sendMessage()
  • Works across threads
Only in the same Javascript thread
  • Timer, timer.schedule()
  • Scheduler:
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
  public void execute() {
    handleMessage(msg);
  }
});

Sockets

Full Sockets Implementation
  • TCP, UDP
HTTP or Websockets
  • No RAW sockets
  • The server needs to "speak" websockets
  • Some (applet|flash)-based raw socket solutions

Local Storage

SharedPreferences
  • Stores key-value pairs of primitive data types
Web Storage API
  • LocalStorage and SessionStorage
  • Stores Strings
  • 5 MB Limit in Chrome
  • Needs a subdomain per app
Storage storage = Storage.getLocalStorageIfSupported();
storage.setItem("key", "value");
storage.getItem("key");

3D Graphics

OpenGL ES
  • Versions 1.1 and 2.0
  • SurfaceView
WebGL
  • Based in OpenGL ES 2.0 (Shaders...)
  • Canvas extension
  • Good performance
  • Library w/ webgl bindings: gwtgl

Interface

  • GroupViews, Views
  • Defined in layout XML files
  • Panels, Widgets
  • Mapped into HTML + CSS
  • You can also define the layout in XML with the GWT Designer
So, interfaces are very different :(

We mapped automatically

Some things were very easy to convert:
  • Toasts / Alerts -> to panels
  • Menu and MenuItems -> to on-screen buttons
  • Preferences Screen -> to a popup Dialog*
* Adding elements manually

Touch Events

Touch Management
  • OnTouchListener, view.setOnTouchListener(...)
  • Also some differences between Android versions
Different Mouse and Touch handlers:
  • MouseDownHandler, MouseUpHandler, MouseMoveHandler, MouseOutHandler
  • TouchStartHandler, TouchMoveHandler, TouchEndHandler, TouchCancelHandler

Typical Problems

  • Emulator is slow...
  • but developing with a real device is fast
  • Many devices / Android versions to test
  • Compilation is slow
  • Compilation requires lots of memory
  • And development mode is very slow
  • Many browsers to test...

But Javascript is fast

GWT-Genetared JS is only a 20% slower than Desktop JRE:
Java (Desktop JRE) 213.681 NPS*
Js in Chrome 170.951
C# (Mono) 156.891
* Nodes per second calculated with my Carballo Chess Engine:
alonsoruibal.com/java-vs-c-vs-javascript/

Our Emulation Library

A very simple library emulating some Android APIs over GWT:
  • Activities
  • Menu and MenuItems
  • AlertDialogs & Toasts
  • SharedPreferences
  • Handlers and Messages
  • Log, FloatMath, SystemClock...
bitbucket.org/mobialia/gwt_android_emu

Muti-Platform libraries

Focused on games, develop against the library API Targets: Desktop JRE, Android, GWT, Flash (embedding Js), iOS (via MonoTouch)...

Publishing

Google Play
  • 25 USD
  • Mobiles, Tablets
  • Millions of devices
Chrome Web Store
  • 5 USD
  • Chromebooks, Desktops (Win, Linux, Mac)
  • Subdomain per app

Packaging apps

APK file
  • You sign the APK and manage certs
Zip File
  • The web store signs the zip
  • Icon & manifest.json:
{
  "manifest_version": 2,
  "name": "Mobialia Chess 3D",
  "description": "World-Class 3D Chess Game",
  "version": "1.1",
  "app": { "launch": { "web_url": "http://chess.mobialia.com/"  }},
  "icons": { "128": "icon_128.png"  }
}

Monetization

  • Purchases & in-app Purchases
  • Admob
  • Great app visibility in Google Play
  • Purchases & in-app Purchases, but only for Chrome
  • Adsense
  • Discovery is difficult

Demos

Our WebGL, Android->GWT games:

Thanks!


Questions?



Alberto Alonso Ruibal
alberto.ruibal@mobialia.com
@albertoruibal
@mobialia

www.alonsoruibal.com/slides/android2gwt/