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
Who am I?
- Previously: J2EE dev, System manager
- Now Android & GWT dev
- Co-Founder at Mobialia
- Twitter: @albertoruibal
- GDG Vigo Co-Organizer
Apps:
- Mobialia Chess
- Gas-Stations Spain
- Slot Racing
We have some Android Apps
And we want them in HTML5
HTML5 is a great platform... for
Desktops:
- Standard
- Offline
- Storage
- Graphics
- 3D
- Multimedia
- ...
But we have lots of Java code
GWT is a magic toolbox that compiles Java to Javascript, and also:
- Removes unused code
- Optimizes
- Obfuscates
- Manages browser differences
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:
- java.net.*
- Files
- InputStreams
- ...
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
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: