October 27, 2008

Android/iPhone comparison

Posted in iPhone development tagged , , , , at 5:43 pm by tetontech

With the release of the G1 phone I decided that I had better take a look at the build process and API for Android applications.

It is interesting but seems to miss the mark.

It is true that it is very easy to create applications for Android.  It is true that you can create the interface programatically or use XML to define it.  So in this way it is similar to iPhone development and interface builder.  There is no tool for graphically creating the XML file that defines the interface.

That being said it is easy for Java programmers to create applications.  In fact with little effort I have created most of the Java side of QuickConnectAndroid in 1 day.  This may be due to my many years of Java development and a previous implementation, unreleased, of QuickConnect for Java.

The development environment is eclipse with an Android plug-in.  It is disappointing that log messages don’t appear to end up in the terminal sub-window in eclipse.  In fact I am still working on finding where all of them go.  I have used gdb with it’s options to view the log file but not all of my log messages appeared.

There is a built in capability for JavaScript to call Java classes in the underlying framework.  This call would be made from WebKit embedded in the android.webkit.WebView object.

The problem, as I see it, is that Android is not as intuitive for users as the iPhone is.  There seems to be an over-reliance on the user interacting with the hardware.  It is not nearly as solid-state as the iPhone is.  For example, if you launch the browser and want to enter a URL, do a search, add a bookmark, refresh the screen, or swap browser ‘tabs’ you must push a hardware button to access the menu.  To go back a page another button on the device, not in the user interface, must be used.

Honestly it took me a while to find this.  I stumbled on it accidentally.  I assumed that the browser would be like a desktop browser or the iPhone browser.  That is to say the browser would be self contained not dependent on hardware activity to display accessing these ‘hidden’ items.

My own personal opinion is that the desktop is a waste of time as is the software menu at the bottom of the main screen used to display all applications.

Add on that there doesn’t appear to be any multi-touch capability and I personally can’t see why someone would pay as much or more for one of these phones as the you would for an iPhone.

If Google wanted to one-up the iPhone this doesn’t do it from a usability standpoint.  It seems that Android was created by engineers for engineers not for ‘normal’ people.

This being said, a version of QuickConnect for Android is such low hanging fruit that I will create one here soon.  I first have to ship QuickConnectiPhone 1.0.  I hope to have it and an example of how to interact with the device, called DeviceCatalog, included in the download.

When the QCAndroid is done you should be able to create an application for the iPhone and Android using JavaScript, HTML, and CSS and have it work on both devices.

Advertisements

4 Comments »

  1. Mike said,

    Nice review on the G1. It is too bad the Google team didn’t have you to help them work on their project. It is really sad that they did so poorly given all of the recent resources and experience that has flooded the industry with the iPhone and all of its “competition”. With Google’s track record combined with how much I like their work, I am really disappointed with what they have produced. I the phone is kind of lame, you would think they would make it really cheap to give it some kind of edge.

  2. Mark Chipman said,

    Lee… this is great. I’m really looking forward to this as I am working on building an app on both the iPhone and soon also on Android. This is perfect timing for me.

    -Mark

  3. tetontech said,

    Todd,

    Some good comments.

    By the way, I am working on an android port of QC.

    At that point most all of an iPhone app or Android app created using it should port directly across to the other platform.

  4. Todd said,

    Here are my notes on android and iphone, w/respect to WebKit, Javascript, and embedded apps:

    * android webapp notes
    * comparison of android and iphone webkit

    ——————–
    Android WebApp Notes
    ——————–

    Here’s how I would start down the web app path:

    1. Is the html/js going to live on a server or be baked into the app?
    This affects your access w/respect to xmlhttprequests in the future.
    There may be a way to break this rule and make unrestricted calls tho
    (calls outside the page domain).

    2. You can mix and match embedded and native controls if you need that
    level of flexibility. Remember that the key to this is adding the
    javascript class to the webview (add it when you create the class
    instance, not in the onPageLoaded() notification).

    3. You could easily create the timer in native land, and then have it
    call into your js context via : loadUrl(“javascript:myjsmethod()”);

    4. Or you could have the js context call into native land if you do #2

    5. Remember to add permissions to your manifest:

    http://code.google.com/android/reference/android/webkit/WebView.html

    Note that, in order for your Activity to access the Internet and load
    web pages in a WebView, you must add the INTERNET permissions to your
    Android Manifest file:

    6. Example for addJavascriptInterface:

    //docs ——–
    public void addJavascriptInterface(Object obj, String interfaceName)
    Use this function to bind a Java object to Javascript so that the
    methods can be accessed from Javascript. IMPORTANT, the Java object
    that is bound runs in another thread and not in the thread that it was
    constructed in.

    Parameters
    obj The class instance to bind to Javascript
    interfaceName The name to used to expose the class in Javascript
    //docs end ——

    #———-

    7. This might have a syntactic error or two, but here’s what I did,
    off the top of my head:

    // 7.a Create the javascript extension
    // this is a class for which all public methods will be added to the
    javascript context
    public class FooJS
    {
    // something nice to do
    public static final String NAMESPACE = “foo”;

    public void allHailMing()
    {
    // do something
    }
    }

    // 7.b Create a class that to embed the webview in:

    // the key things are:
    // * add the java script context
    // * config your wv settings, i think js is turned off by default
    // * add a webviewclient, nec. for callbacks from the wv

    //Someclass
    public class Someclass
    {
    WebView wv = new WebView();

    // there are other websettings you’ll want to look at, too
    WebSettings ws = wv.getWebSettings();
    ws.setJavaScriptEnabled();

    // for testing, it’s better not to cache your js
    ws.setCacheMode(LOAD_NO_CACHE);

    // add the js context, and give it a namespace to reference the libs
    // this is the way i do it, but you could also do
    // wv.addJavascriptInterface(new FooJS(), “myNamespaceFoo”);
    // however, don’t get fancy, i don’t think nested namespaces are
    supported, ‘foo.bar.com’
    wv.addJavascriptInterface(new FooJS(), FooJS.NAMESPACE);

    //Now, for any sort of web callbacks, you have to use the WebViewClient:
    WebViewClient wvc = new WebViewClient(){
    @Override
    public void onPageFinished(wv, url)
    {
    // do something cool, for example, you could call some js in the
    embedded webview, or start your container (native) timer
    Someclass.getTimer().start();
    // here we invoke the js that we added to the js context, note the use
    of the namespace
    wv.LoadUrl(“javascript:foo.allHailMing()”);
    // or you could invoke js that was there before
    wv.LoadUrl(“javascript:originalMethodInJavascriptPage()”);
    }

    // this is really cool for debugging, for one thing, it will intercept
    // your alerts and instead of popping them up on screen, the code below
    // intercepts them and prints them to stdout
    @Override
    public void onReceivedError(WebView view, int errorCode, String
    description, String failingUrl)
    {
    system.out.println(description + “:” + failingUrl);
    }
    }
    }

    ————————————
    Comparison Android and iPhone Webkit
    ————————————

    iPhone:
    * doesn’t support extending the javascript context on the device,
    major problem for browser extension (or so I thought.now I need to
    look closely at quickconnect)
    * String evalJavaScriptFromString(String s) returns the string result
    to the container, which is nice and simple

    Android:
    * DOES support extending javascript context on the device, which means
    you can expose any device capabilities or java libs to the javascript
    context
    * the loadUrl(String s) // where s is of the form
    “javascript:function()” will invoke methods in the js context (and
    actually calls evalJavaScriptFromString lower in the WebKit stack) but
    does NOT return the string result.so you have to push it into the
    container manually

    e.g.

    #container js lib
    hashtable ht
    public class jslib
    {
    public setValue(String key, String value)
    {
    ht.put(key, value);
    }
    }

    #javascript
    function foo()
    {
    //do something
    jslib.setValue(somekey, somevalue);
    }

    # container
    loadUrl(“javascript:foo()”);

    Note: This execs on a different thread in the js context, so you’ll
    want to put a listener on your hashtable wrapper class to react to
    foo() setting a value in the container’s hashtable.

    Also, the lack of long running processes on the iPhone is a huge
    hindrance.

    Android annoyances:

    * forced serialization of your activites when the activity goes to sleep
    * not all objects are serializable (like webviews, for example)
    * not all objects continue running view isn’t loaded (webviews)
    * threads are flaky, esp. when you have threads + animations, the
    threads (timers) forget to fire
    * writing animations as xml may be powerful, but it’s hard to get them
    to look nice (on the emulator, anyway)

    Android niceness:

    * xml layout and resources makes duplicating apps (languages, similar
    apps, whatever) a breeze.
    * droiddraw() is a basic graphic designer for android xml layout. Nice
    to get you started.
    * full access to the hardware, although you can bet that tmobile is
    going to try everything in their power to prevent voip type apps.

    ** This is cool, android provides a thread queue out of the box for
    delegating code/messages to fire on the UI thread (actually, it’s
    whatever thread it’s instantiated on, but the typical use case is to
    instantiate it on the ui thread). This means that you do this:

    #ui class
    public class myActivity extends Activity
    {
    public Handler handler = new Handler();
    }

    Now, in other class, that can be on any thread, you can simply do this:

    myActivity.handler.send(new Message(.));

    or

    myActivity.handler.invoke(new Runnable(.){ public void run(){.}});

    This will save you a HUGE amount of debugging trying to figure out
    how/why you borked the ui.

    If I had the time, I’d be writing an application suite that leveraged
    a core set of intents and/or activities. And I’d be following the strategy of
    web apps in a native container. That is hands down the fastest way to
    create apps. Except that I’m not a web guy. (again, now that
    quickconnect has arrived, I’ll check that out)

    However, here’s something that I’ve thought of trying: use apple’s
    dashcode as your html designer (poor man’s dreamweaver). Both android
    and iphone are using webkit, so the entire app should port. Then
    factor out the jslibs, wrap them, and expose them like:

    #client_wrapper.js

    if( defined(js_android))
    {
    // invoke android container methods
    else if ( defined(js_iphone) )
    {
    // invoke iphone container methods
    }

    Here are the projects that I’ll be investigating next:

    * Quickconnect
    * http://ejohn.org/blog/iphone-javascript-apps/
    * http://inexdo.com/JSCocoa
    * http://phonegap.com/

    -Todd


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: