Sunday, July 22, 2012

using gwt-phonegap

This post is part of a series of blogposts that show the usage of  some mgwt / gwt-phonegap components.


For quite a while I wanted to write a blog post on how to use mgwt and phonegap together to write great mobile apps.
While mgwt provides all the mobile widgets, animations and touch support you need, gwt phonegap provides access to the phonegap api.
Combining them means being able to write mobile apps with GWT that look beautiful and behave exactly like native apps.

Some background
GWT compiles Java to Javascript. With Phonegap you can write Apps in Javascript. Basically we just need to take the output of the GWT Compiler and put it on the phone.

Which files to include
In general you will have a html host page, like you have with any GWT app. With a phonegap app this will include at least the javascript for the phonegap api (cordova-x.x.x.js) and your gwt no cache file.
An example html host file would look like this:


<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>name of your app
    <!-- phonegap api -->
    <script type="text/javascript" language="javascript" src="cordova-1.x.x.js"></script>
    <!-- gwt module include -->
    <script type="text/javascript" language="javascript" src="yourgwtmodule/yourgwtmodule.nocache.js">
  </head>

  <body>
   <!-- gwt history frame -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0">
  </body>
</html>


You can see the include for the phonegap api. Note: It is important that phonegap is included first!

I would recommend keeping the html host file seperate from the one you are using for a web app, since with a web app you will not have a phonegap include.
Your deployment script however needs to copy the complete module folder (gwt output) as well as other needed resources to the phonegap www folder.

In Phonegap all HTML + CSS + Javascript files need to be inside the www folder of your phonegap project. If you are using phonegap plugins you might also be adding code. (Java for Android, Objective-C for iOS and so on)
If you have never used phonegap you might also be interested in a good guide on how to setup phonegap.


The gwt phonegap part gives instructions on how to setup a GWT with gwt phonegap.
The main idea behind gwt phonegap is to provide two implementations of the phonegap api: one that is using the phonegap javascript API on a device and the other is a pure emulation api that enables developers to build phonegap apps while running gwt dev mode.
To ensure that there are no runtime penalties gwt phonegap uses deferred binding and compiles different implementations for emulation and phonegap environment. This is done by the phonegap.env variable.

This means that you can use any phonegap module inside the browser and still call all phonegap api. (For specific limitations see every modules documentation )


A simple Hello World Phonegap demo would look like this:

final PhoneGap phoneGap = GWT.create(PhoneGap.class);

phoneGap.addHandler(new PhoneGapAvailableHandler() {

 @Override
    public void onPhoneGapAvailable(PhoneGapAvailableEvent event) {
     // build your ui and caLet ll phonegap
        String phoneGapVersion = phoneGap.getDevice().getPhoneGapVersion();
        RootPanel.get().add(new HTML("Using phonegap version: " + phoneGapVersion));

    }
});

phoneGap.addHandler(new PhoneGapTimeoutHandler() {

    @Override
    public void onPhoneGapTimeout(PhoneGapTimeoutEvent event) {
        Window.alert("can not load phonegap");
    }
});

phoneGap.initializePhoneGap();



Summary - Setup Projects
Let me walk you through the necessary steps to get a GWT app on a phone with phonegap.
I am assuming that you set up a phonegap project as described in the phonegap documentation for your plattform.
This is the shell for your web app to run on a phone. It has a www folder where we will store our web app.

The next step is to setup a standard GWT project.
In this project you need to at the gwtphonegap-1.x.x.x.jar to your classpath. You can do this manually or use maven to do this.
After adding the jar to your classpath you need to add the following line to your gwt xml file:

     <inherits name='com.googlecode.gwtphonegap.PhoneGap' />


This tells the GWT compiler that you want to use the gwt phonegap project. After that you can start using the phonegap object in your code (see example).

At one point you want to get your application on an actual phone. Now you have to compile the app using the GWT compiler and copy the output of the GWT project (your module folder) to your www folder of your phonegap project.

For a a release of an app you only want to copy the relevant files for the actual permutation. mgwt has a special permutation map linker for that. It outputs xml that lets you easily find the necessary files for the right devices. This will be covered in another blog post.

Sunday, July 8, 2012

mgwt - Going mobile with GWT & Phonegap

This post is part of a series of blogposts that show the usage of  some mgwt / gwt-phonegap components.

mgwt is a library for developing mobile apps and mobile websites with GWT from one code base. mgwt provides native looking widgets for many platforms, animations and many other things that are needed for writing mobile apps. gwt-phonegap enables GWT apps to use Phonegap. With Phonegap HTML5 apps can access the same device features that native apps can use from Javascript, such as the file system or contacts.
With mgwt and gwt-phonegap you can deploy your GWT apps into any app store or let your users use them as a website.
Both projects are available under apache 2.0 license from maven central.


Features
mgwt provides mobile widgets that are compatible with UIBinder and the Editor Framework. mgwt integrates touch events and animation events with its own DOM implementation and provides gesture recognizers on top of that.
There are themes for iPhone, iPad, android phones, android tablets and blackberry. For going offline there is an automatically generated HTML5 offline manifest.
In dev mode gwt-phonegap can emulate the Phonegap API so that developing of Phonegap apps can happen inside GWT dev mode. gwt-phonegap also provides utilities to make GWT RPC work in a Phonegap environment.

Performance
mgwt uses GWT core concepts like Client Bundles, deferred binding, GWT MVP and many more. mgwt tries to leverage GWT features as much as possible, enabling the GWT Compiler to do optimizations.
Mobile devices do have much slower CPUs, less bandwidth and are running on battery. Building inefficient apps means draining the users battery. Since GWT is very good at optimizing Javascript apps it is a natural fit for writing cross platform mobile apps.

mgwt leverages the GWT Compiler and HTML5 to get really good performance on mobile. Here are a few examples:

No Graphics
Most of the styling can be done only by using CSS3. This reduces apps size significantly. The following screenshots do not contain any images

.
[Image1 - Slider on iPhone]    [Image2 - Slider on Android]



Theming with Client Bundles
mgwt uses GWT Client Bundles for styling to ensure that unused CSS can be removed by the GWT Compiler.  This means e.g. if an app is not using the slider widget the CSS won`t be inside that app.

Going offline aka no download
Mobile devices are not always connected to the internet. Therefore mobile web apps need to be able to start while being offline. This can be achieved with the HTML5 offline manifest. The GWT compiler sees all artifacts during compilation. This is why mgwt can generate the manifest files for different permutations at compile time. This means that an android device will only download and store the necessary android files, while an iPhone sees a different manifest.

Minimal markup
Keeping your DOM minimal makes your apps run fast. mgwt tries to use as few DOM elements as possible, while doing styling in CSS.

Layout with the flexible box model
If layout feels fast the application feels fast. Therefore layout should not be done in Javascript,  CSS should be used instead. The browser can calculate and apply the layout in its native code which is going to be much faster than doing calculations in Javascript.
With HTML5 there is the flexible box model which is supported by all important mobile devices and can be used to achieve any layout that you need for mobile. mgwt uses the flexible box model heavily to build its layouts.

Animations with CSS3
For mobile applications it is quite common to have animations. If Javascript would be used for animating, the browser has no change to optimize. If you want fast animations you need to give the browser the knowledge of the whole animation, so that it can figure out a fast way to execute it. This can be done with CSS3 animations.
mgwt uses different kinds of CSS animations depending on the platform so that animations always feel fast.

Want to learn more? Checkout the mgwt homepage and the blog. There is also a 90 minutes talk on mgwt from the dutch GTUG.

Saturday, July 7, 2012

mgwt and the viewport

This post is part of a series of blogposts that show the usage of  some mgwt / gwt-phonegap components.



If you are writing software for mobile phones you should know about the view port meta tag and what it can do for you.
There are different settings for the viewport that let you do different things.
Browsers on mobile phones are different from desktop browser in the sense that they have this notion of the viewport. The screen on an average mobile phone is not big enough to fit a normal webpage. This is why the viewport was invented. It allows mobile browsers to display webpages that are made for desktop devices by zooming and moving the viewport around.

If you don`t supply any information to the browser it will render your page zoomed out. It will try to give the user a good overview of the page so that he can decide on which part he needs to zoom in.
Normally text will not be readable.

You can control the initial scale, the maximum scale and the minimal scale of the viewport with a meta tag.

Setting an inital scale will set the value lets you control the zoom value at startup.
With mgwt it would look something like this:


   ViewPort viewPort = new MGWTSettings.ViewPort();
   //configure view port
   viewPort.setMinimumScale(0.2).setInitialScale(1.0).setMaximumScale(5);

   //create settings and set view port
   MGWTSettings settings = new MGWTSettings();
   settings.setViewPort(viewPort);

   //apply the setting e.g. create meta tag in page
   MGWT.applySettings(settings);


This code would result in a meta tag looking like this:
   <meta name="viewport" content="initial-scale=1.0,minimum-scale=0.2,maximum-scale=5">

If you are writing app you do not want the user to be able to zoom your app. The webpage should feel like a native app. This can be done by setting the initial screen scale to 1.0 and disabling scrolling.

With mgwt this would look like this:

   ViewPort viewPort = new MGWTSettings.ViewPort();
   viewPort.setUserScaleAble(false).setMinimumScale(1.0).setInitialScale(1.0).setMaximumScale(1.0);

   MGWTSettings settings = new MGWTSettings();
   settings.setViewPort(viewPort);
   settings.setPreventScrolling(true);

   MGWT.applySettings(settings);

This will create a meta tag that looks like this:
   <meta name="viewport" content="initial-scale=1.0,minimum-scale=1,maximum-scale=1,user-scalable=no">

Depending on what you are trying to do you need to set different values for the viewport.
mgwt gives you the freedom to set any value that make sense to you.

If you want to have the default settings for an app you can use a short handle like this:

   MGWT.applySettings(MGWTSettings.getAppSetting());


I hope gives you the necessary information to use viewport effectively to build your mobile app with mgwt.

As always feel free to leave any comments or suggestions.

Thursday, July 5, 2012

mgwt & super dev mode

This post is part of a series of blogposts that show the usage of  some mgwt / gwt-phonegap components.

GWT Super Dev Mode is a very nice way of seeing your changes on a mobile device very quickly.

Unfortunately it`s not that easy to use with a mobile browser. This is why I built a direct support for it into mgwt.

The basic idea:

The GWT Super Dev Mode consists of a so called code server which skips many of the standard GWT optimizations and thus is able to produce Javascript from Java very fast. You can run it alongside your nomal GWT Dev Mode. On browsers that support source maps you can even do Java debugging in their Javascript Debugger.

Right now the support in mgwt is considered experimental, because I might change some bits based on your feedback.

Setting it up:

Requirements


  • GWT 2.5 rc1 (or later) from here
  • latest mgwt trunk (1.1.2-SNAPSHOT) from here

Configure SDK in Eclipse

Go to Prefrences -> Google -> Web Toolkit. Click on the add button and browse to the GWT 2.5 installation directory:





After adding the SDK, make it your default SDK. You list should look something like this:





Setting up your gwt.xml file & Entrypoint

In your gwt.xml file you need to add the following lines:




<add-linker name="xsiframe"/>
<set-configuration-property name="devModeRedirectEnabled" value="true"/>
<set-configuration-property name="mgwt.superdevmode" value="on" />

If you want to run your GWT CodeServer from a different host or port you also need to add:

<set-configuration-property name="mgwt.superdevmode_host" value="http://<yourhost>:<port>" />

In your Entrypoint you will have to add the following line, which will compile out if you turn off mgwt.superdevmode:


SuperDevModeUtil.showDevMode();

Setting up your Run Configuration to start Super Dev Mode

Inside Eclipse you need to create a Java Run Configuration. Go to your Run Configurations, select Java and press New:




On the first tab (Main) you can set a decent name and the project to use.
The main class you need to start is: com.google.gwt.dev.codeserver.CodeServer






In the arguments we need to pass a bindAddress as you know from a normal GWT dev mode, since with mobile devices we will not use it locally. Also we need to specify the Module to use. In my case it looks like this:
(Programm Arguments)
-bindAddress 0.0.0.0 com.googlecode.mgwt.examples.showcase.Showcase

In the VM Arguments make sure to give it some RAM, something along the lines of:
-Xmx1024m








In the class path tab you will need to add the gwt-codeserver.jar which you will find in your gwt installation directory and you will also need to add all folders with source code to the project. (The Codeserver operates on Java files)

You can add a folder by selecting User Entries, click on Advanced -> Add Folder and select the source folder of your project.






My classpath looks like this:





Now you can just start the code server. It will take some time but at the end it should print something like this:

The code server is ready.
Next, visit: http://:9876/





Compile your mgwt app once with the normal compiler

Now you need to compile your gwt module once the normal way and open it with your mobile phone / tablet. This is your normal gwt app that runs on the jetty server (http://yourpost:8888 by default) You should see something like:




If you click "Super Dev Mode On" you will see this:

Now you can hit compile, which will compile the app and reload the page:

Important: Super Dev Mode saves its state (turned on) inside session storage. So if you want to see the normal compiled app, you will need to hit "Super Dev Mode Off".



Round up

With this integration of Super Dev Mode into mgwt it will be much easier to test features on a device. I am seeing compile times less than 4s for many of my projects, which is a major improvement.
I am looking for feedback on this one. If you have some good suggestions on how to improve this, please let me know!