Enabling WebView remote debugging in KitKat

26 Feb

My current application is targeting multiple versions of Android, but I’d also like to enable the remote debugging features of KitKat’s new WebView. This creates a problem when trying to maintain API compatibility, as the methods to enable debugging don’t exist on older versions of Android.

Here’s the snippet of code I’m now using to get around this problem – it leverages Java’s reflection API to allow us to enable debugging, but only if it’s available on the platform. Make sure you augment your Android application’s main Java file correctly.

public class CustomerView extends WLDroidGap {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);		
        
        // Enable remote debugging, if available! - KitKat or more
        if (Build.VERSION.SDK_INT >= 19) {
            if (0 != (getApplicationInfo().flags = ApplicationInfo.FLAG_DEBUGGABLE)) {
                try {
                    Method m = WebView.class.getMethod("setWebContentsDebuggingEnabled", boolean.class);
                    m.invoke(null, true);
                } catch (Exception e) {
                    // Oh well
                }
            }
        }
    }
    
}

How to make your generated widget’s DOM IDs reflect their AMD module

14 Nov

In the new AMD world, it’s suggested that we omit the specification of a “declaredClass” in our custom widget’s declare() call, like so:

define(["dijit/_WidgetBase"], function(_WidgetBase) {
    return declare([_WidgetBase], { 

    })
});

However, in this case, _WidgetBase doesn’t have a specified value for declaredClass, and uses the declaredClass from an appropriate parent class to automatically generate a DOM ID.

I’ve worked around this so far by using a pattern like this:

define(["module", "dijit/_WidgetBase"], function(module, _WidgetBase) {
    return declare(module.id, [_WidgetBase], { 

    })
});

Hopefully we’ll see some fixes from Dojo here to make this easier in future.

Destroy all widgets/dijits in a DOM node

31 Oct

Following up on Tom’s post from 2011, and taking into account the comments posted, here is the latest “known good” technique.

Often we need to empty a DOM node of all widgets. Here’s the magic incantation.

require(["dijit/registry", "dojo/dom-construct", 
        "dojo/_base/array"], 
        function(registry, domConstruct, array) {

    // Your DOM node reference goes here
    var node = null; 

    // Destroy the widgets, including their
    // children and DOM fragments
    array.forEach(registry.findWidgets(node), 
        "item.destroyRecursive()");

    // OPTIONAL: Explicitly empty the node.
    // This will take care of DOM nodes that 
    // weren't managed by widgets
    domConstruct.empty(node);

});

dojox/mobile :: Programmatic View transitions

28 Oct

When programmatically initiating View transitions, we have two choices. Given the following markup, we can initiate a transition between view1 and view2 in two ways.

<div data-dojo-type="dojox/mobile/View" id="view1" selected="true">
   stuff
</div>
<div data-dojo-type="dojox/mobile/View" id="view2">
    more stuff
</div>

Option 1: View.performTransition()

dijit.registry.byId("view1").performTransition("view2", 1, "slide");

See the dojox/mobile/View API for full details.

Option 2: new TransitionEvent().dispatch()

require(["dojox/mobile/TransitionEvent"], function(TransitionEvent) {
    var view1 = dijit.registry.byId("view1");
    new TransitionEvent(view1.domNode, {
        moveTo: "view2",
        transition: "slide",
        transitionDir: 1
    }).dispatch();
});

See the dojox/mobile/TransitionEvent API for basic details.
It is possible to write a basic wrapper around this function to simplify your code.

Which to use

Option 1 (View.performTransition) looks simpler, but it does not handle transitioning to nested views correctly in some cases, leaving ancestor views invisible.

Option 2 (new TransitionEvent) is recommended. It handles these edge cases correctly, establishing the correct “from” and “to” views, and ensuring ancestor views are visible.

Worklight 6.0 and Dojo integration

14 Oct

The new Dojo tooling in Worklight 6.0 has left a number of people confused. In this post, I’ll explain how the various resources and settings in a new Worklight 6.0 project interact, and how to change these to achieve the desired effect.

Continue reading

Chrome Developer Tools Tricks

16 Sep

This post is a round-up of some of the less-known debugging tricks I’ve learnt about related to the Chrome Developer Tools window. You might know some, but hopefully there’s at least one in here which is new.

Formatting

Suppose you are reading some badly-formatted JavaScript code from a developer with no respect for formatting. Or maybe (and hopefully more likely), you are reading some code that’s been through a minification process, such as the Dojo Build System. Either way, it’s possible, from with the Sources window, to hit this button on the bottom-left:

1

That turns the mess of JavaScript into something more cleanly-formatted and readable:

2

Tracking down exceptions

Sometimes, you’re dealing with code with which you’re a little unfamiliar. For example, a page might load, but isn’t displaying correctly, and you’re not sure why. You’re suspicious that there’s an exception being thrown somewhere which might narrow down the problem, but you’re not sure where. That’s where the “Pause on exception” button comes in handy:

3

Clicking it toggles between 3 states:

  • Dark grey = Off
  • Light blue = Break on all exceptions
  • Dark purple = Break only on uncaught exceptions (ones not caught by a try/catch block)

The last state is by far the most helpful; caught exceptions aren’t usually that interesting, as they typically indicate an “expected” path in the code; uncaught exceptions, on the other hand, are normally cause for concern. This button can help you establish more quickly where code is going awry.

An Anti-Trick: Disabling Cache

Browser caching has been for a long time – and remains – the bane of a web developer’s existence. Chrome has attempted to address this issue by adding a “Disable cache” checkbox inside the Developer Tools settings window:

4

5

However, be aware that this only works whilst the Developer Tools window is open. If, like me, you are limited in screen space, you may be in the habit of closing Developer Tools when you aren’t actively debugging a site. In that case, this checkbox won’t take effect. In that case, you’ll have to rely on another method, such as manually clearing the cache.

Hardware accelerated Android emulator on Mac OS X

6 Aug

The Android emulator can be extremely slow when running in the default ARM emulation mode.

Fortunately, Google and Intel have worked together to give us a much faster alternative – the Intel Hardware Accelerated Execution Manager (HAXM).

I’ve had trouble getting this to work on Mac OS X in the past. I’m sure this should be documented somewhere, but sadly my Google fu is lacking today, so here is a quick summary of what I’ve recently learnt is needed to make it work.

Continue reading

Follow

Get every new post delivered to your Inbox.

Join 77 other followers