February 27, 2009

Android, WebView and AJAX

Posted in Android Development tagged , , , , , , at 3:35 pm by tetontech

Thankfully, as of Google’s release of Android 2.0 the XMLHttpRequest object is now included and supported as is the in-browser database and the CSS animations and transitions.  Welcome to the party Google.  It’s about time.

OK.   An update……  The XMLHttpRequest object does exist but it doesn’t work.  I ended up implementing my own http handling inside of QuickConnect.  Too bad Google.  You’re making our work harder.

The statement below still applies to pre 2.0 Android.

There has been some buzz about how to do AJAX from within the WebView component of the Android platform.  Unfortunately Google has not included the XMLHttpRequest object in the implementation for reasons they only know.  As I have scoured the web on this topic I have found many statements about how a work around ‘should’ be able to be done, some statements that simply state that it can not be done, and others saying that Google gears solves the whole problem.

Here is the reality.

Can it be done?  Yes.  Is Google gears the answer?  No.  It uses the XMLHttpRequest object.

I have spent a significant amount of time exploring possibilities.  The solution requires a call from JavaScript down to the Java layer of the application.  Simply stated, the Java code uses the HTTP classes, Connection , Client, etc. to make the request and the result is then passed back up to JavaScript.

The ‘gotchas’ are as follows.

  1. The return value of a call from JavaScript to Java can only return primitives and strings, not objects.  Therefore no type of complex dom-like object can be retrieved directly.
  2. The Android API requires that all communication from Java to JavaScript be done in the form of a URL change for the WebView.  This means that data must be URL encoded on the Java side and decoded on the JavaScript side.
  3. The URL encoder on the Java side doesn’t match the decoder on the JavaScript side.  The spaces in the data are converted to ‘+’ characters which remain ‘+’ characters in the JavaScript decoder.  This requires that the implementer of a library replace all instances of the space character with some other sequence on the Java side,  I used ‘_SpA_, and then replace all of the placeholder sequences with spaces on the JavaScript side.
  4. The javaScript dom parsing object doesn’t handle XML well.  The parsed result of an RSS feed isn’t even close to the XML it is sent.

After spending over a week exploring the possibilities I have come to the following conclusion.

The best way to get AJAX access within Android’s WebView objects is as follows.

  1. Make a call from JavaScript to Java including the URL.
  2. Using the Java-side HTTP objects make the request including any cookies stored on the Java side that may be needed.
  3. After receiving the completed response from the server determine the data type.
    1. If the data is JSON or HTML URL encode it.
    2. If the data is XML send it to Android’s SAX parser.
  4. Send the data to the JavaScript side of the application
    1. If the data is JSON or HTML do this directly
    2. If the data is XML use the SAX events to produce a JSON string that represent the XML node in question and pass the JSON for this node back up to JavaScript
  5. URL decode the data when it gets to the JavaScript side and put any spaces back in the data
  6. Handle the data in JavaScript
    1. If the data is JSON or HTML take any steps appropriate for you application.
    2. If the data is XML assemble a dom-like node structure as each individual JSON string representing a node is received.  Once the entire ‘dom’ document is built use it as if it had been obtained using the XMLHttpRequest object.

This approach will work.  My tests indicate that this type implementation could mimic the XMLHttpRequest’s functionallity but not necessarily its’ method structure.  They also indicate that implementations that use the Java side to make AJAX requests will be too slow.  Data sets of any significant size require to much encoding and decoding to be efficient.

I would hate to go through the very large development cycle required to do the implementation described above only to have Google wise up and include the XMLHttpRequest object.  At this point in time there are QuickConnectFamily roadmap items that seem much more feasible and demand my time.  If AJAX support becomes critical to QCAndroid developers I am willing to do an implementation with the understanding that it may not be usable for significantly sized data sets.

At this point QuickConnectAndroid will not have AJAX support because of the WebView object’s limitations.  The hope is that Google will realize it’s mistake and put the XMLHttpRequest object back in the WebKit engine implementation for the WebView Java object.  Pressure from the development community on Google may be of help here.

22 Comments »

  1. Keith said,

    Any updates since 2.0.1 or 2.1 have been released?

    • tetontech said,

      I tried this last week. The last update still applies to Android.

  2. scott said,

    It works just fine for me.

    Maybe you forgot to enable javascript for your WebView:
    mywebview.getSettings().setJavaScriptEnabled(true);

    • tetontech said,

      I use Javascript all over in the WebView. Maybe there is a new version that is now working. I’ll check it out.

      • Donald said,

        I have been trying to find the answer to this question. Does the WebView support AJAX?

      • tetontech said,

        It has been a few months since I checked but at that time the answer was still no. I wrote my own implementation on the Java side. That is part of the download.

      • Donald said,

        I tried it and I THINK it works. However I am 1000 issues that I am not sure are related. Things like clicking on a text box does not display the keyboard, the web application uses the device’s current location, that just hangs. All of these work just fine when hosted in the browser. I really don’t know what to do.

      • tetontech said,

        It sounds like the other issues are not connected directly to AJAX. The WebView in Android may not contain all of the elements and behaviors in the Android browser. Google has pulled this on us before.

        It would be easier for me to help you if you send your project to me to look at. barney.cit@gmail.com That way I can see what calls you are making and do some experimentation.

        I won’t share it with anyone else.

  3. fla said,

    I tried AJAX trough jQuery today on Android 2.1 and it works likle a charm.

    • tetontech said,

      I’ll try it again as soon as I get my Android installation working again. What version of Android SDK were you using?

      • Donald said,

        Yep seems to work just fine with 2.1. The issues I was having I initially thought were AJAX et.al. related. Thanks for the help.

  4. Andrew said,

    On Android 2.1 , you can add 2 users permission in AndroidManifest.xml and it’s work.

    AndroidManifest.xml :

    • Austin said,

      What 2 user permissions are those?

  5. William said,

    Hi,

    I really need to Handle AJAX in webview…. Is there is some code snapshot somewhere to show how to do it (in code). I would use the Previous development step (Thanks a lot tetontech you are the rare person on the net that speak about a solution) but if someone has already developed it or developed part of it I don’t want to reinvent the wheel.

    If I get some code help I will be able to develop it faster and I could share the code I ended up with following the tetontech recipe as well.

    Let me know if any of you have a starter or a main course for me ;o)

    Cheers,

    William

    • tetontech said,

      William,

      If you are using Android 2.1 and later it should be working for you. If not then code will have to be written. I haven’t created code because of the 2.1 inclusion of AJAX functionality.

      Are you working on pre 2.1?

      Lee

  6. William said,

    Hi Lee,

    I’m indeed using the version 1.5 and I don’t think I can have the 2.1 for this platform. How much time it will take me you think to code it myself. Couldn’t I include the missing libraries from 2.1 myself to compensate?

  7. William said,

    Hi Lee,

    I’ve end up find a 2.1 version for my platform recently published. So I did the upgrade instead developing the code from which you show the steps.

    I did have a look about the integration of AJAX via The XMLHttpRequest object but there is no sign of it in the official Adroid developer ref manual.

    As well I didn’t find any example of its implementation on the net. Could you give me a snapshot of the code you used to handle AJAX by getting the request from the server and transforming the AJAX code in conventional Javascript to display the proper outcome in Webview browser?

    Tanks

    William

    • tetontech said,

      William,

      If you download QuickConnect from sourceForge you will find it has a file in it called ServerAccessObject.js. In there you should find all of the manipulation of the XMLHttpRequest object that you need.

      You will probably want the QuickConnectAndroid download assuming you are running on Windows or Linux. If you are on OS X then get the QuickConnectFamily download.

      Lee

      Lee

  8. William said,

    Hi Lee,

    Thanks for the Tip. I did look into it.

    With the Webview framework from Android 2.1 the AJAX request work on the net.

    In fact what has happen is that I am using i-jetty as server within android and it doesn’t handle automatically AJAX. I am currently implementing dwr in i-jetty server to develop asynchronous com between client and server as well as XML parser and converter javascript to java.

    Android do not handle DOM library properly yet so I have to include external libs to do the job.

    Once finish I hope to have a client/server on Android that support most of the required functions.

    William

  9. steve88est said,

    I am able to a get data using xmlhttp after setting the following code in manifest

  10. steve88est said,

    <uses-permission android:name=”android.permission.INTERNET” /&rt;

  11. vedhashree said,

    I am able to a get data using xmlhttp but

    xmlDoc.load( xmlhttp.responseXML);
    xmlDoc.onload=getmessage

    is not invoking the gemessage call in android.

    am using android 2.2

    kindly help


Leave a comment