Introduction
A while ago, me and my friend Martin were invited to speak at the excellent Devoxx Conference in Antwerpen, where we were to give a presentation about hybrid applications in Android. We were delighted to get the chance to explain how hybrid applications really works, for we’ve noticed that it’s a topic that people really don’t know much about? The subject has been lively debated for the past couple of years and there’s an abundance of articles listing the pros and cons of hybrid apps, but, except for a couple of articles explaining the basics, that’s about it. What we really think is missing is a deep dive into the technical details of hybrid applications, where more advanced concepts are discussed. Be aware, that this is not a general, good to know, introduction to hybrid applications in general; it’s an Android centric tutorial that focuses solely on how you can take advantage of web content in Android.
What we’ll do
This article is based on a simple hybrid application, that we wrote for the Devoxx conference. The goal of this tutorial is to go through the entire application and show you how it’s done. I’ll describe the application with screenshots and simple drawings, and break it down into smaller digestible pieces that we’ll examine and implement. I’ll cover everything from loading web pages and communicating between Android and the web content, to creating a consistent theme and adding css transformations to make the user interface look slick.
The application
The application is a simple image viewer that displays seven images at the same time. Image 1 and Image 2 shows screenshots of what the application’s main screen look like.
Image1. Seven, differently sized, images are displayed. The images are loaded from the device storage and different web pages
Image 2. No action no fun. The application changes the images by rotating them a 180 degrees, along the x-axis. Here, the middle image is being rotated.
Image 3. The full image being displayed together with some clickable icons at the bottom. Clicking one of the icons will bring up a dialog showing additional information about the image, like comments, a map, or wikipedia information.
There are a few things, not obvious at first glance, that are at the core of this application. First of all, the rotating images; have you noticed that the rotation is done in 3D. OK, so what? 3D isn’t exactly rocket science, and it could easily be done using OpenGL. Sure but, assuming that you know OpenGL, isn’t it a bit overkill for a simple application like this to use a technique like OpenGL? That’s where the web can help us. I’m going to do the image rotation using css transformations, which is a simple, hardware accelerated, and well known web technique. Below is an overview of how the css rotation works.
Image 4. One card dissembled into smaller parts. The ‘Card’ is the container, made-up from a simple ‘div‘ tag in html. The Card contains two images, a back- and a front image. Using css, the two images are arranged on top of each other, with the back image turned upside down. When it’s time to rotate the card we simple apply a transformation that will rotate the div tag a 180 degrees. We will discuss the implementation more deeply in part 3.
Secondly, and this is impossible to see from the screenshot, the application is structured using the MVC pattern, where the controller and model is implemented in Android and the view is HTML. For a regular application this is nothing new, but for a web application it will be a bit different.
Application Architecture
As I said, the application is built using the MVC pattern, where the web is the view, and Android represents the controller and model.
Image 5. The application uses the MVC pattern.
This means that all ui operations are implemented in HTML, Javascript, and CSS, while the logic (what picture to show, when to rotate them, etc.) is implemented in Android. When it’s time to change an image, a “command” is sent from Android to the Web component, telling it to update a specific image. This is a simplified description of how it works, but as we progress (part 2 focuses on communication), you will get a better understanding of it.
That’s it, we know enough about the application to get started. Now you know what we are going to do, what it will look like, and how we are going to structure our application. Let’s go on and take a closer look at the Android web component.
Android Web Component
The web component contains four important classes that we will use.
Image 6. The web component consists of four important classes. The WebView is the class that you’ll be working most with, the other three classes are merely customisation points, where you can change the behaviour of the WebView.
WebView
The WebView is a regular Android view, capable of showing web content. The web view contains a wide range of methods, everything from telling the WebView to go back or forward, to capturing pictures of the web content and clearing the cache. The description of the web view might fool you into thinking that it’s a full blown web browser with navigation buttons, history and a reload button. It’s not. The WebView contains the logic for doing all of these things, but there is no user interface, at least not anything resembling what we think of as a browser. The WebView is, simply put, a rectangle containing web content; by default javascript isn’t even enabled and some of the functionality, like alerts, doesn’t work. To remedy this shortcoming, we need to add our own custom WebChromeClient and WebViewClient. Image 7 shows what a plain vanilla WebView looks like.
Image 7. WebView with our company page loaded.
Below is the code for this masterpiece.
[java]
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
webView.loadUrl(“http://blog.jayway.com”);
setContentView(webView);
}
[/java]
Loading a web page is straight forward, just create a WebView and load a URL. What you don’t see in the above image is that there’s something missing on the page.
WebSettings
Compare the web page, loaded in the previous section, with what it looks like in a real browser.
Image 8. On the right side: what the page looks like in a standard WebView. On the right side: what it should look like.
The two images looks similar but there is one component missing in the image to the left; a javascript image switcher is missing, because a WebView doesn’t support JavaScript out of the box. To remedy this shortcoming we can change our implementation to something like the code below, where we’re using the WebSettings object to turn on JavaScript.
[java]
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(“http://blog.jayway.com”);
setContentView(webView);
}
[/java]
WebSettings contains a large set of methods that you can use to change the behaviour of the WbView; it contains methods that disables all network loading (effectively making sure that your page is only loading local content), adding build in zoom controls, and setting the path to the local web database, just to mention a few of them. For a complete list of WebSettings methods see API
WebViewClient
WebViewClient handles everything that, in some way, is related to the rendering of a page. It lets you add callback methods that is invoked to inform you of changes in the rendering. Start and stop loading, loading specific resources, errors, login, and form resubmissions are typical examples of things that you will be notified of in the WebViewClient.
To add a task for execution, when the page has finished loading, add this:
[java]
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// Do stuff here
}
});
[/java]
What if you want to handle errors? Let’s say that you’re trying to connect to a server, how can you know that everything went alright? The code below listens for errors and prints some simple log statements.
[java]
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view,
int errorCode,
String description,
String failingUrl) {
Log.e(getClass().toString(), “Error code: ” + errorCode );
Log.e(getClass().toString(), “Description: ” + description);
Log.e(getClass().toString(), “Failing URL: ” + failingUrl);
}
});
[/java]
The error codes are described in the WebViewClient; you’ll find errors like “ERROR_BAD_URL”, “ERROR_CONNECT”, and “ERROR_TIMEOUT”.
The WebView contains a bunch of other methods that you can implement to get callbacks from the WebView when something happens. Check out the API for more information.
WebChromeClient
It can be difficult to separate the WebViewClient from the WebChromeClient since they both, at least when you start to learn about them, seems to cover the same responsibilities. To keep them apart, think of the WebChromeClient as the class responsible for everything browser UI specific while WebViewClient is responsible for everything that is related to the rendering of the web content.
The WebChromeClient let’s you handle the browser’s visited history, create new windows, take care of alerts, prompts, and console messages. Let’s add some code to handle alerts:
https://gist.github.com/4335589
WebChromeClient and WebViewClient contains a number of methods that your are free to override in order to customise the WebView. A simple application with no requirements on the integration will be fine without overriding any of the methods while a more demanding application will require you to implement all of them.
Summary
In this first post, we’ve learn the basics of the web view and what the different classes are responsible for and how they work. In the next article I will start to implement the main view, containing the seven images.
very good articles, thank you
Brilliant article – looking forward to the second part!
Great work, would like to check out next post.
Good writing.complex content in simple text.waiting for the second part. if possible please provide full source code.
Man, good article but I think you have forgotten to insert the code snippets ;) I can’t see anything in Chrome and neither IE…
very nice dude….
i have also found one good example here
Use MVC Pattern To Create Very Basic Shopping Cart – Android Example
Nice tutorial,thanks ……………………….
Android flutter tutorials similar to hybrid
http://www.androidcoding.in/tutorials-flutter/
You have explained the topic very well. Thanks for sharing a nice article.