Post image for More Fun with Mixed Titanium Android Modules

More Fun with Mixed Titanium Android Modules

by Bill Dawson on 8 April 2013

In my previous post, Overcoming TIMOB-13097 in Titanium Android Modules, I discussed adding Javascript to your Titanium Android module in order to overcome a particular problem (see the post for details.)

In this post I want to expand on the idea of “mixed” (Java and Javascript) modules by suggesting a few other ways in which including Javascript can be beneficial to your module.

Performance

If you are able to move some of your module’s logic outside of your Java code and into Javascript, you might benefit from a performance boost. I cautiously use the word “might” here since I’m not running any tests just now to confirm it. But the idea is that if some of your module’s api calls (methods, etc., made available to app developers who are using your module) are Javascript-only, they avoid crossing what I and others like to call “The Bridge”, or simply “Kroll” (or “The Kroll Bridge”). In our case, crossing the bridge means leaving the nice, quick native environment of C++-based V8 execution and entering the Java virtual machine.

Note that it’s quite easy to cross the bridge accidentally, such as by calling a method on an object acquired via the bridge (our “proxy” objects, such as views, etc. — basically anything Titanium.*). But if you can make something purely Javascript, you can avoid the bridge.

Documentation and “Javascriptyness”

One of the things I dislike about my Titanium Android Animation module is the documentation. (I’m glad I did any documentation, but still…) Using doxygen to process the Javadoc tags inside the module’s Java code was relatively convenient for me, but the output leaves much to be desired. The fact is, Javadoc is — surprise — for Java, not Javascript, so it can be difficult to use Javadoc tags to accurately describe the equivalent data types.

The venerable Arthur Evans turned me on to JSDuck, which he uses for the Titanium API documentation. One thing I love about it is that its default generated output is definitely good enough for me (stylistically) and therefore requires no intervention by my non-existent design skills. But beyond that, it is a Javascript documentation engine. Whether you’re writing your modules in Java (for Android) or Objective-C (for iOS), they will be used in Javascript, so composing your documentation from the get-go with a Javascript documentation generator really helps you think up-front about the API from a Javascript developer’s perspective.

Of course, to use JSDuck effectively, you need to put your module API in Javascript. I’ve started doing that now. Basically all of my modules going forward will be primarily Javascript-based. Some of the methods, properties, etc., might simply be wrappers that do nothing more than call the Java-based proxy methods and properties, but I’m still going to do it this way because (to recap):

  • It helps me see and anticipate how Javascript developers will use the module.
  • JSDuck is awesome.
/**
 * @class MyModule
 * Does all sorts of fancy stuff.
 */
function MyModule() {
  /**
   * @method doSomething
   * Does something really
   * fun to the thing you pass.
   * @param {Object} thing
   * The thing you want stuff
   * done too.
   * @param {String} thing.name
   * A display name for the thing.
   * @returns {MyModule} this instance
   * so you can chain.
   */
  function doSomething(thing) {
      // ...
  }
}

exports.MyModule = MyModule;

Intellectual Property Protection

Your Titanium Android module’s Java code (assuming you don’t obfuscate it) is easily readable. Someone just needs to buy your fancy, premium module at the Marketplace, unzip it, find the JAR file and open it in something like JD-GUI. Even if you obfuscate, you at least need to keep your API methods and properties named the same as they are in your module API documentation, so it likely wouldn’t be too difficult to figure out your code.

Your module’s Javascript code, however, is encrypted by means which are far more mysterious. It would be more difficult (though by no means impossible) for someone to read your module’s Javascript code.

Keep in mind, however, that any functions you export (or which are accessible as values of objects that you export) can easily be read at runtime:

var x = function() {
    return "My super secret stuff";
};
console.log(x);

That code will show this in logcat:

I/TiAPI (20483):  function () {
I/TiAPI (20483):    return "My super secret stuff";
I/TiAPI (20483): }

So in your module’s Javascript, you can avoid exposing your super secret stuff by exporting only a wrapper:

function superSecret() {
    return "Doing something really secret!";
}

exports.superSecret = function() {
    superSecret();
};

Note: There may still be a fancy way to get to the unexported function. I’m just not aware of it. Leave a comment if you know.

Comments on this entry are closed.

Previous post:

Next post: