CMake, C++, and TDD


I’m in the middle of an experimental C++ fibonacci program in an attempt to familiarize myself with CMake. I barely know “Make” and now I’m ankle-deep in CMake. How did I get here? It began as part of my exploration into C++ TDD. I’ve been periodically playing with C++ testing tools trying to find a comfortable way to develop some decent cross platform logic. My exploring took me to mnmlstc/unittest. Hi, I’m Cliff. You’re here because you write unit tests. I’m here trying to find the appropriate way to do so in C++.

there’s not much to blab about tonight. I’m only passing #define macros from a config header template through to my c++ logic and scratching the surface of integrating tests with CMake. So far I’ve learned that configuring the install target of your make file uses a default prefix of “/usr/local” when you use relative paths but you can override this by using absolute paths. I’ve also learned how to “add_definition”s.

I’m a long way from mnmlstc but I’m having fun. Hopefully I’ll have some decent object models emerging from my experiments… and hopefully these models will be properly coded in C++11. Have you ever tried to understand a new technology from the eye of a test framework you’ve never used before? Me neither…

Git sparse checkout


I just wanted to share something in git I learned rather recently. Don’t laugh either because I I know a whole lot of you are probably like, “git experts” and thinking… “c’mon son? You just now figuring that out?” If that is you keep your mouth shut. This post is not intended for you. It is instead intended for those of you who are still parked in the Subversion mindset. It is for Old timers like myself who are delighted when they finally figure out what the rest of the tech community has been raving about for years. Hi, I’m Cliff. you’re here because you’re getting long in the tooth and trying to keep up with technology. I’m here because my teeth are just as long. I’m also here to tell you that you really don’t need to clone the whole git repo.

Here’s the story (because a lot of my posts have some sort of backstory): I was trying to figure out how to get gdb working in a Gradle-managed Android Studio project. Y’see, I’ve already managed to get an Android Studio project with a native component to build and run on both the device and the emulator. Now I’m trying my hand at C++/gdb debugging. Something I’d never done even on a regular ant managed project. (What’s that? You didn’t know that you can use Android Studio and Gradle to build/run an Android project with native libraries? Stay tuned for the updated post that I thought I’d already told you about!) That venture got me looking for the source to the Android plugin for Gradle. There are a couple of android plugins but I wanted the one that was running as part of my Android Studio project. I found the source and was intimidated by the layout of the source on Google’s site. Intimidated, I immediately told myself I wasn’t trying to checkout the entire thing onto my tiny 256GB HD. I have a strong distaste for checking out projects with huge a source base. (I later learned that the part that I needed to check out wasn’t really all that big and negated the need for both my exploration into git sparse checkouts and this rather long blog update but it was a fun exercise none the less.) So here’s the short instructions on how to do it. I found out from this S/O post.

Assuming you want to checkout the new Gradle build system but only want the gradle subfolder from the 4.3_r0.9 tag as I did you would do something like this:

$ mkdir android-tools
$ cd android-tools/
$ git init
Initialized empty Git repository in /Users/clifton/dev/android-tools/.git/
$ git remote add -f origin https://android.googlesource.com/platform/tools/buildUpdating origin
remote: Counting objects: 15, done
remote: Finding sources: 100% (15/15)
remote: Total 11593 (delta 2852), reused 11593 (delta 2852)
Receiving objects: 100% (11593/11593), 6.09 MiB | 2.49 MiB/s, done.
Resolving deltas: 100% (2853/2853), done.
From https://android.googlesource.com/platform/tools/build
* [new branch] jb-mr1-dev -> origin/jb-mr1-dev
* [new branch] jb-mr1-dev-plus-aosp -> origin/jb-mr1-dev-plus-aosp
* [new branch] jb-mr1-release -> origin/jb-mr1-release
* [new branch] jb-mr1.1-dev -> origin/jb-mr1.1-dev
* [new branch] jb-mr1.1-dev-plus-aosp -> origin/jb-mr1.1-dev-plus-aosp
* [new branch] jb-mr1.1-release -> origin/jb-mr1.1-release
* [new branch] jb-mr2-dev -> origin/jb-mr2-dev
* [new branch] jb-mr2-release -> origin/jb-mr2-release
* [new branch] jb-mr2.0-release -> origin/jb-mr2.0-release
* [new branch] master -> origin/master
* [new branch] tools_r21 -> origin/tools_r21
* [new branch] tools_r22 -> origin/tools_r22
* [new branch] tools_r22.2 -> origin/tools_r22.2
* [new branch] version_0.5 -> origin/version_0.5
* [new tag] android-4.2.1_r1 -> android-4.2.1_r1
* [new tag] android-4.2.1_r1.1 -> android-4.2.1_r1.1
* [new tag] android-4.2.1_r1.2 -> android-4.2.1_r1.2
* [new tag] android-4.2.2_r1 -> android-4.2.2_r1
* [new tag] android-4.2.2_r1.1 -> android-4.2.2_r1.1
* [new tag] android-4.2.2_r1.2 -> android-4.2.2_r1.2
* [new tag] android-4.2_r1 -> android-4.2_r1
* [new tag] android-4.3_r0.9 -> android-4.3_r0.9
* [new tag] android-4.3_r0.9.1 -> android-4.3_r0.9.1
* [new tag] android-4.3_r1 -> android-4.3_r1
* [new tag] android-4.3_r2 -> android-4.3_r2
* [new tag] android-4.3_r2.1 -> android-4.3_r2.1
* [new tag] android-cts-4.2_r1 -> android-cts-4.2_r1
* [new tag] android-cts-4.2_r2 -> android-cts-4.2_r2
* [new tag] android-sdk-support_r11 -> android-sdk-support_r11
remote: Counting objects: 4, done
remote: Finding sources: 100% (4/4)
remote: Total 4 (delta 0), reused 4 (delta 0)
Unpacking objects: 100% (4/4), done.
From https://android.googlesource.com/platform/tools/build
* [new tag] version_0.5.0 -> version_0.5.0
* [new tag] version_0.5.1 -> version_0.5.1
* [new tag] version_0.5.2 -> version_0.5.2
* [new tag] version_0.5.3 -> version_0.5.3
$ git config core.sparseCheckout true
$ echo 'gradle/*' >.git/info/sparse-checkout
$ git checkout android-4.3_r0.9
Note: checking out 'android-4.3_r0.9'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b new_branch_name

HEAD is now at 70d8da9... Merge "Move version to 22."

As you can see above there are quite a few tags associated with this project but so far the sparse checkout seems to have worked as advertised. I’m not sure how much space savings I’m seeing over cloning the entire project but hopefully this tip will serve to help others, or myself as I sometimes look over old posts to remember how I did something.

Can your IDE do this?


So I’m tapping out a test method in my favorite tool for developing mobile software and it looks like this:

View errorMessage = errorDialog.findViewById(findIdForStringIdentifier(ERROR_MESSAGE_TEXT));
assertTrue("Expecting a TextView field", errorMessage instanceof TextView);
errorMessage.get

Then I notice… no, scratch that I don’t even notice that auto-complete has sprung into action and is offering me the proper completion at the top of the list, “getText()”. It happens in the most subtle way as my subconscious mind already knows what it wanted to do and it directs my fingers to accept the completion. What I end up with is:

View errorMessage = errorDialog.findViewById(findIdForStringIdentifier(ERROR_MESSAGE_TEXT));
assertTrue("Expecting a TextView field", errorMessage instanceof TextView);
((TextView) errorMessage).getText()

Hi, I’m Cliff. You’re here because your IDE doesn’t do what my IDE does. I’m here because I’m ecstatic over what I’ve learned in the last 10 minutes. Look again at the above code snippets, both before and after and follow what happened in between. The important part is where the 1st line establishes a local variable of type “View”. To my amazement auto complete picked up and inferred it was a type of TextView when I started keying the 3rd line and it offered me not just any random or alphabetized list of suggestions but a preferred suggestion that matched exactly what was being conjured up in my grey matter. (For those unfamiliar with Android programming, a view does NOT include a “getText()” method.) And while I didn’t have to futz with the usual, “oh… I have to either declare my local type as a TextView or add a cast” my IDE does this inference then later performs the cast on my behalf keeping my cursor within the proper context so I can continue adding logic. It happened so “matter of fact” like and so quickly that I didn’t catch on until I had completed typing the line at which point I had to do a double take.

How does it know I need a TextView? Is it because of the preceding assert with the “instanceof” comparison? Does it just naturally assume most views will need to be eventually cast to a “TextView” type because that’s all most Android devs know how to use anyway? Is it reading through the xml layout and determining the type based on the integer id returned from my custom “findIdForStringIdentifier” that is taking a String constant id? Has Jetbrains quietly figured out how to read brainwaves over my Mac’s wifi antenna? I don’t know and I don’t really care!

I had done similar programming in other IDEs (Eclipse, Netbeans, X-Code, Visual Studio) but never have I ever had such an experience where an IDE literally read my mind, did the excessive back-spacing, parenthesis wrapping, casting, and continuation of thought for me. It’s these little nuggets that I keep finding in IntelliJ Idea that keep me addicted. I could go on for days on how wonderful this one… read it… ONE experience, out of hundreds of similar experiences, made my life today but I won’t. I’ve argued the merits of Idea to plenty of developers over the years but until you actually experience how do they put it…? “Development with pleasure” Until you actually live out a few of these scenarios you will continue to grind out code the usual way, hitting refresh/rebuild project to clear the red squiggles that really shouldn’t be there, dealing with arbitrary auto-complete suggestions, not truly being able to refactor code effectively as you could otherwise.

Robolectric, Ivy, Maven repo drama


For those of you who know me (which would include most people reading this post) you’ll note that I am a huge proponent of TDD and proper project hygiene. I describe project hygiene as the things you do to ensure a successful project with easy maintenance. I have recently been working to prototype such a project in Android but have been hitting several roadblocks along the way. Hi, I’m Cliff. You’re here because you want a nicely structured project. I’m here because I can’t seem to get my project in the right shape, so I’m complaining.

I started a while ago with an example chat app I had written as a guide to using IntelliJ to write Android apps. I even put up a video tutorial on the subject. I recently had been working to reuse my example which had a hard dependency on the Robolectric project. Robolectric is a cool toy that lets you perform REAL unit tests on Android. There are those who may say, I do unit tests all the tim using Robotium, or the Android JUnit packages… but these are not unit tests as they involve either the emulator or a physical device. The tests I have written run successfully on my laptop and take a fraction of the time that typical Android tests take.

I had my environment working about 7-8 months ago but so much has changed since then. Today when I tried to recreate my magic I had trouble trying to “install” Robolectric on my new Mac. (All my work had been setup on my old Mac.) I originally tried running with the older 1.1 Robolectric jar but then had to tweak my IDE envirnment variables to point to ANDROID_HOME which is so much fun on Mountain Lion these days. (It’s practically impossible to get IntelliJ to see custom system environment variables and the launchctl trick doesn’t work for me.) So the nI eventually decided after forcing ANDROID_HOME and getting a path not found on “~/android-sdk-macosx/platforms/android-10″ since my new Mac doesn’t have the older SDKs to install a later version of Robolectric. My thinking was, “maybe they’ve ironed out the details and finally fixed it so you don’t need env variable settings and older SDKs…”

If you visit the Robolectric home page you’ll see all the installation instructions point to a Maven POM. that does you no good if you’re starting from an existing Android project because it either
a.) Forces you to refactor your project using Maven standards
b.) Forces you to reverse engineer the pom to find out where the actual Robolectric jar is.
Both of these options are terrible for existing Android work and since many people rarely get to work on green field this presents a tough dilemma.

I eventually found a way to work around the issue by whipping up an equivalent ivy.xml and throwing together a custom_rules.xml to use in my Android project but it still sux on the surface because of the extra overhead involved with declaring a single Maven dependency in an Android project.

Step 1: create a custom_rules.xml.
Step 2: declare an Ant “-pre-build” target that performs the ivy resolve task and writes the dependecy jar files to your project’s “./libs” folder.
Step 3: create a custom ivy.xml that declares your Maven dependencies.
Step 4: Cuss because you realize it’s not trivial to invoke your custom “-pre-build” target in isolation to test your new configuration.
Step 5: Create a custom “ivy-resolve” target which your new “pre-build” target should now depend on.
Step 6: Test your “ivy-resolve” in isolation to ensure it pulls the correct dependencies.
Step 7: Cuss because your IDE’s built-in version of Ant does not include the Ivy jar.
Step 8: Either find the Ivy jar hidden on your hard drive and dump it into your IDE’s antlib or find your custom ant build tools and point your IDE to that.
Step 9: Repeat step 6
step 10: Cuss because your project’s “libs” folder has now exploded with unnecessary transitive dependencies including everything from ant to maven-model.jar to wagon to xerces.jar
step 11: Try to run your tests and realize that the dependencies declared don’t line up with the examples from the web site.
step 12: construct a blog post expressing your frustrations with the current state of Android development.

In the end I’m wondering why, in the year 2013, we can’t do any better out of the box. Why is it still a chore to practice proper TDD on mobile platforms? (I’m glaring at the iOS community as well because I don’t think that camp is any closer to out of the box TDD.) I would love to just open my IDE, click on a unit test, perform some hotkey combo Cmd+shift+F10 or something, and watch either red or green bars stretch across the screen without considering silly stuff like my environment, grabbing older SDKs, researching dependency matrices and the like.

By the way, I found out how to pull external dependencies into an Android project following this blog post. Nice little trick!

You need permission


You’re writing an Android app and you need to do something slightly more than trivial. Maybe you want your app to snap a picture, maybe you need to capture audio. Maybe you just need to track where the user is. At any rate, your app needs permission to do certain things. Hi, I’m Cliff. You’re here because you’ve asked permission from your user base to do a bunch of stuff. I’m here because I’m learning the ins and outs of Android permissions. Destiny has brought us together and I’m glad to meet you.

I was going to make another long winded post but it’s late and I have other things to do. I’ll just sign off with a link to a site that documents some Android permissions. Maybe you’ll find it useful. You’re welcome!

http://techblogon.com/android-permissions-list-example/#

Talking Web Views


You got this one web view with Javascript and you want to talk to Javascript running in another web view, for reasons that I’m totally unsure of. Maybe you want to impress the girl in the coffee shop with your hard core coding expertise. Maybe you wanna go for a promotion and your manager is all like, “I need to see you innovate!” Maybe you think it’s just cool to load two web views that know one another. Hi, I’m Cliff, you’re here because you want to tote two web views. I’m here to show you how it’s done.

I haven’t posted anything in a month of Sundays. I never understood why people use dumb phrases like “a month of Sundays”. If there were only Sunday “days” in the month then it would be kind of short because you only get four of them… and that doesn’t seem like it makes much sense. I say that because people use that phrase to indicate long elapsed periods of time and a month of Sundays is only four days. People should just get over themselves and say I haven’t seen you in four days without all of the, “I need you to do the Maths and figure out what I’m talking about”. People are dumb. I digress.

I was beginning to tell you about this thing I’m doing with web views. I did it because I’ve been asked how to do it like two times. I got tired of pretending to know what I’m talking about so I prototyped it and I’m going to post my stuff here and just point to this page from now on. Plus, like I said earlier it’s been a month of Sundays (or four days if you don’t like Maths). So here goes. For those three of you who visit regularly I’m sorta back but not quite. Testing the waters a bit.

Back to these talking web views… the idea is simple. a mobile app with Javascript in one web view makes something happen in a second web view in the same app. To make it work you need to know two things, how to call from Javascript into native code and how to call from native code into Javascript. Tonight’s example will demonstrate how we will demonstrate how this is done on Android but I can show the same example on iOS.

Let’s start with main layout saved in a file call main.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <WebView
            android:layout_width="fill_parent"
            android:layout_height="250dp"
            android:id="@+id/myWebView"
            android:layout_gravity="center"/>

        <WebView
            android:layout_width="fill_parent"
            android:layout_height="250dp"
            android:id="@+id/secondWebView"/>
    </LinearLayout>
</FrameLayout>

We have a linear layout set to vertical orientation. There are two nested WebViews defined, “myWebView” and “secondWebView”. Each will appear one above the other. Next we define a main activity.

package com.example.JavascriptBridge;




import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;




public class MainActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        WebView myWebView = (WebView) this.findViewById(R.id.myWebView);
        myWebView.getSettings().setJavaScriptEnabled(true);
        //Magic Javascript handling class to be defined later
        final JavaScriptHandler scriptHandler = new JavaScriptHandler(this);
        myWebView.addJavascriptInterface(scriptHandler, "MyHandler");
        myWebView.loadUrl("file:///android_asset/view1.html");
        WebView otherWebView = (WebView) this.findViewById(R.id.secondWebView);
        scriptHandler.setRelayWebView(otherWebView);
        otherWebView.getSettings().setJavaScriptEnabled(true);
        otherWebView.addJavascriptInterface(scriptHandler, "MyHandler");
        otherWebView.loadUrl("file:///android_asset/view2.html");
    }
}

We set Javascript enabled on both views. We have a magic Javascript handler class which we will define next. This is a custom class which we stuff inside the first WebView using the addJavascriptInterface() method on the WebView class. This method makes ordinary Java objects appear as Javascript objects to code running inside a WebView. (We will soon add Javascript code that makes calls on the magic class.) Next we load an HTML file, “view1.html” into our first view. We grab our second WebView and give it to our JavascriptHandler which will relay information from the first WebView. We setJavascript enabled on the second WebView and put our magic JavascriptHandler object in it as well, just for good measure. We load view2.html as the content for the second view.

Let’s see our first HTML file, view1.html:

<!DOCTYPE html>
<html>
<head>
    <title>Javascript Bridge</title>
</head>
<script>

</script>
    <body>
        Java/Javascript Bridge example
        <form id="inputform">
            Value to pass: <input type="text" name="user_input">
            <input type="button" name="pass" value="relay!" onclick="window.MyHandler.setValue(inputform.user_input.value)">
        </form>
    </body>
</html>

Not much here. There’s a typical HTML form with an input text field and a button. The onClick() action of the button has Javascript that talks to a special object called “MyHandler”. This object was defined in the Activity above, if you recall these lines:

        final JavaScriptHandler scriptHandler = new JavaScriptHandler(this);
        myWebView.addJavascriptInterface(scriptHandler, "MyHandler");

The handler, which we’ll define next, exposes a setValue method. We call this method and supply the value from the earlier input text field. Let’s see the magic inside the custom JavaScriptHandler class definition.

package com.example.JavascriptBridge;

import android.webkit.WebView;

public class JavaScriptHandler {
    MainActivity parentActivity;
    private String value = "unset";
    private WebView relayWebView;

    public JavaScriptHandler(MainActivity activity) {
        parentActivity = activity;
    }

    public void setValue(String val){
        this.value = val;
        relayWebView.loadUrl("javascript:second_inputform.second_user_input.value='" + value + "'");
    }

    public String getValue() {
        return value;
    }

    public void setRelayWebView(WebView relayWebView) {
        this.relayWebView = relayWebView;
    }
}

Inside the JavaScriptHandler custom class we have a WebView property, relayWebView which we saw used in the MainActivity. There is also a value property but inside the property set method we have additional logic to relay the value to the relayWebView property. We do this by calling the loadUrl() method on the relayWebView and passing in javascript code using the “javascript:” protocol. (When you ask a WebView or web browser to load a Url prefixed with the “javascript:” protocol is will execute any javascript included after the protocol prefix.) The Javascript assumes there is a “second_inputform” with a “second_user_input” text field and attempts to set the value of this text input. Let’s look at the view2.html which we load into the relayWebView from the MainActivity.

<!DOCTYPE html>
<html>
<head>
    <title>Javascript 2nd Page</title>
</head>
    <body>
        Passed value shows here!
        <form id="second_inputform">
            Value Received: <input type="text" name="second_user_input">
            <input type="button" name="button" value="reset" onclick="second_inputform.second_user_input.value='enter text above'">
        </form>
    </body>
</html>

Here you see the “second_inputform” with the “second_user_input” text input. So when the earlier Javascript is injected and executed you will see the text from the first WebView relayed to the second WebView. That’s the entirety of it! Since I haven’t posted source in what we used to describe as a “month of Sundays” but now understand should be much more than a four day-long month, it’s going to take me a while to figure out how to glue my example project to this blog post.

I used to be so much better at gluing code to blog posts but these days I don’t even remember how to log in to my site as the administrator. With any luck, the code will be found as an attachment or maybe something with a little paper clip icon hanging on the side bar. I’m not really sure but I’ll figure that out now. There! I just remembered the Box widget on the right hand side. You can find my Jvascriptbridge.zip project there. Until next time… which might not take an entire month of Sundays if I get my act together…

Getting one’s act together is another one of those things people say. I’ve never acted nor do I belong to a drama club, so I would have a hard time getting my act together. For example, if I had an “act” how did it become disassembled in the first place? I would imagine various pieces of what would have been “my act” scattered randomly on the floor. I would probably hire somebody to piece it back together because I suck at act assembly. That would take a while because last time I looked in the Yellow Pages there was no section for “Act Assemblers”. I could find “Plumber”, and “Doctor” just fine. “Mechanic” was there, as well as “Actor” but not “Assembler”. It’s late, and I probably should go now. If you’re into programming stuff, check back. I promise I won’t ramble senselessly on my next post… unless you like my rambling. And if you do like it maybe I’ll put up one of those PayPal links so people can pay me for rambling. Yes it’s late. I should do other stuff like sleep. Thanks for reading! :)

When refactoring goes horribly wrong


You’ve been down this road before. You’ve added a parameter to a constructor and now you have 2 parameters with similar names. You merely want to distinguish between them both. A quick lookup to see how the original parameter is used reveals that it is not an “id” rather it is a shortcut. After refactor/rename action in your IDE  you wait for satisfaction which should only take seconds. Several minutes tick away while a progress bar fills, refills and is eventually joined by several other progress bars each taking their time to fill to completion. Hi, I’m Cliff. You’re here because you’ve been staring at your screen patiently waiting for several progress bars to bring you refactoring pleasure. I’m here for much of the same reason.

Every so often I hit an area in my code that doesn’t refactor exactly as I had anticipated. It happens much less frequently since I’ve moved back into Java development and can use the world’s best refactoring IDE. Still it does happen from time to time. This morning I was bit when I attempted to rename a class member named “id”. Apparently the my IDE is having trouble tracking down all 5 usages in the current file as it scans my entire project for these 2 very common characters. I’m not sure why it’s happening (it’s still running as I type) but I am guessing it is because I inadvertently left the “scan all non-code usages” option checked. I’ve had much worse war stories of refactoring under XCode which I will save for the future but I felt compelled to share today’s horror story since it is so rare that I have such headaches these days.  Refactoring is actually my favorite part of development as I incrementally massage horrific code into easily managble bite-sized chunks but every so often it pays to watch which options you leave checked in the refactor dialog.

IntelliJ Screencast


You have a killer idea for an Android app. You’ve discussed it with the few folks who matter most, your buddy, your barber, and the clerk at the local convenience store where you buy your lotto tickets on Thursdays. They all agree you have a winner now all you need to do is create it! Hi, I’m Cliff. You’re here because you’re moments away from pushing the next $$multi-million app to the Android Market. I’m here to prepare you with the correct tools and know-how. Below is my 1st screencast, an introductory tutorial for using IntelliJ Idea. IntelliJ is what I consider to be the best IDE on the planet.

There’s “no such method” to my madness, man…


So you’re writing a web application and it, like, needs to run on one of the many mobile devices invading society these days. You need to invoke a function or a method that doesn’t exist on the class you’re dealing with. You won’t know the name or arguments of the function until the Jaavscript begins executing on the mobile device. Hi, I’m Cliff. You’re here because you can’t predict your functions and methods in advance of coding your application. I’m here because I wanted to post a really quick tip for those of you dealing with crazy Javascript on a modern browser.

Ruby, Python, Groovy, and even Objective-C have a menas of catching and interpreting functions or methods that have not yet been defined. It’s one of those new cool-kid programming tricks that these languages employ which allow developers to define programming languages that take the shape of the problem they are trying to solve. (See write-ups on BDD, and DSL to understand further.) Javascript, historically, has lacked such features. Notice I say historically… I’ve been studying just such a feature enabled by a magic method called __noSuchMethod_. I’ll be spending the next few days understanding its feasibility and limitations on a mobile web browser. That along with the Java to Javascript bridge feature in Android. Check it out and you can thank me later…

I’d like to show you my Weinre


…and if that didn’t get your attention maybe this will. I was looking for a way to interactively debug Javascript running on my Android phone when someone else went and showed me his Weinre. It is completely “Banonkers” (That’s “bananas” and “zonkers” together, I just heard a political correspondent coin this phrase on some news show, no joke…) and totally useful if you have anything web related and of reasonable complexity that needs debugging/tracing through the client.

Follow

Get every new post delivered to your Inbox.

Join 250 other followers