Duplicating Android App Eclipse project

When developing an online Android app, it is easy to put in a switch whether it should run in live/test mode. After the initial live release however, there might be a need to install both versions on a single device. To create an identical Eclipse project with a different package name manually, you need to do a few steps:

  • Copy the project to a different folder.
  • Change the Eclipse project name in the .project file to be able to import it into the same workspace.
  • Load the project into eclipse.
  • Use refactoring to rename your application package.
  • Change all other references to your package, especially in the Android manifest.
  • Change app launcher know, so you’ll know which is which.

This simple windows batch file below does exactly that automatically. You no longer have to manually re-create or synchronise all changes into your test project, just run the script and build.

It uses the open source Find And Replace Text tool, or FART for short. It is a small program with no dependencies.

Don’t forget to change the variables on top and to add other things that may be necessary for your particular project. The example below assumes a standard Eclipse Android project, with the app_name variable specified in strings.xml. Read more ›

Share Button
Posted in Blog Tagged with: , , ,

NumGuess D and Go

Two more versions of NumGuess have been added: the D and Go programming languages, bringing the total up to 35 different implementations/languages. They can be found in the usual GitHub repo under numguess.d and numguess.go respectively.

These are the result of random Google searches to find new languages that haven’t been done yet. If you can think of any you’d like to see that has an easily usable Windows/Linux compiler or interpreter and can make programs that run in the command line, please let me know in the comments below. Or write it yourself by the guidelines and submit a pull request, they’re always welcome.

Share Button
Posted in Blog Tagged with:

Google Street View encounter

Google is transporting a bust of Lenin on a Friday morning in Manchester.

Google is transporting a bust of Lenin on a Friday morning in Manchester.

This is the first post in the aside category, in which I might post other unrelated rubbish that has nothing to do with anything.

Share Button
Posted in Blog Tagged with: ,

Deleting hundreds of thousands of files on Linux

A badly configured server which leaves hundreds of thousands of temporary files in a single folder is a bummer. Not being able to delete them easily is even more so. I tried the standard rm -rf ./*, but all I got was the following error message:

/bin/rm: Argument list too long

I tried to devise more clever patterns to delete them in chunks but it was just horribly slow anyway. This blog post from Hosting Blog came to the rescue with the following terminal command:

find . -name 'pattern*' | xargs rm

Poof! Four hundred thousand files disappeared in a few seconds. Awesome stuff!

Share Button
Posted in Blog Tagged with: , , , ,

Screen recording on Android 4.4 KitKat

While doing a demo of an Android app, I was looking for a way to easily capture the device screen. Turns out it’s not that simple.

There are quite a few solutions available on the Play store, but they either require a rooted device or taking screenshots resulting in choppy video at best, or a slideshow at worst. The Android emulators are also having performance issues, and not all of them have Google Play Services installed, which was required for my app.

Using a physical device, I went with Android 4.4’s built-in screen recorder that can be accessed from the command line. It usually results in a nice smooth recording, but you probably need a higher-end device. Apart from the choppy first couple of seconds, I had no issue with it on Samsung Galaxy S5 and the Galaxy Note 2 was quite acceptable as well.

Step-by-step

  • You have to install the Android SDK on your PC.
  • Using the SDK manager, download and install the platform tools package.
  • Enable developer options on the device and activate USB debugging.
  • Your device will need to be connected to the PC while recording.
  • Start/stop recording from the command line to save video to device storage.
  • Download video from device and profit.

Read more ›

Share Button
Posted in Blog Tagged with:

Upgrading Eclipse 4.3 Kepler to 4.4 Luna

Eclipse Luna logoEclipse 4.4 Luna was recently released along with Google’s Android ADT 23 upgrade. Just like the previous version, upgrading is fairly simple, although I ran into an error on one of my PCs that needed a manual fix. Some issues with ADT and the Android SDK can also be expected as some file paths changed from the previous version.

Upgrading Eclipse

The upgrade process is exactly the same as before: change your software repositories, check for updates and install them. If you’re using other repos, it is a good idea to export the URLs, just in case the repo settings get wiped after the update, which seems to happen often for me. It is recommended to install all updates to Kepler before upgrading to Luna.

Read my previous post with detailed instructions and screenshots if you’re not sure where to look, just make sure you use the new URLs listed here.

Eclipse 4.4 Luna repositories:

In case you’re using Eclipse for Android development, the ADT repo hasn’t changed:

As with 4.3 Kepler, the splash screen will not change on the first restart after the upgrade. Just restart the IDE again to confirm that you’re running the latest version. Read more ›

Share Button
Posted in Blog Tagged with: , , ,

Querying and filtering JavaScript objects and arrays

Another powerful feature of Mangler.js is checking if an object or value satisfies a test expression. A test expression is a javascript object literal with special properties, very similar to and inspired by MongoDB‘s .find() method.

Using test expressions, there are a number of different methods which help you filter and extract parts of your collection, as well as finding the first or last item that passes the test. Here are some quick examples:

var stock = [
	{
		id: 1001,
		name: 'Apple',
		price: 0.50,
		qty: 150,
		tags: ['fruit', 'red'],
		expiry: new Date('2014-06-16')
	},
	{
		id: 1002,
		name: 'Banana',
		price: 1.20,
		qty: 30,
		tags: ['fruit', 'yellow', 'seedless'],
		expiry: new Date('2014-07-10')
	},
	{
		id: 1003,
		name: 'Cherry',
		price: 2.50,
		qty: 220,
		tags: ['fruit', 'red'],
		expiry: new Date('2014-06-19')
	},
	{
		id: 1004,
		name: 'Grapes',
		price: 0.80,
		qty: 130,
		tags: ['fruit', 'green', 'seedless'],
		expiry: new Date('2014-07-12')
	}
];

// Find cherries by ID and return object
var cherry = Mangler(stock).first({ id: 1003 });

// Find all red fruit and put them in an array
var red_fruit = Mangler.find(stock, { tags: ['red', 'fruit'] });

// Create mangler object then narrow down list to cheap seedless fruit
var m = Mangler(stock).filter({ price: { $lt: 1.00 }, tags: ['seedless'] });

// Register custom Date getter for querying the number of days left
Mangler.registerType(Date, {
	get: function(date, key) {
		if(key === 'daysLeft') {
			var oneDay = 24 * 60 * 60 * 1000; // Milliseconds in a day
			return (date.getTime() - Date.now() + Date.now() % oneDay) / oneDay;
		}
	}
});

// Get all items that expire in the next 7 days
// As of 2014-06-15, matching items are apple and cherry
var thisWeek = Mangler.find(stock, { 'expiry.daysLeft' : { $gte: 0, $lt: 7 } });

Functions and methods

Before going deeper into the test expressions themselves, here is a list of all the functions and methods of the Mangler.js library that can be used for querying and testing. In the following spec, <value> is any javascript value, like a string, number, or object. Test expressions will be marked by <test>.

All functions and methods use Mangler.test(<value>, <test>) internally, which returns true if a single <value> satisfies the <test> expression.

Static methods of the library for testing items contained in any iterable object, such as arrays:

  • Mangler.find(<iterable>, <test>) returns an array of all items in <iterable> that passes the <test>.
  • Mangler.first(<iterable>, <test>) returns the first item of <iterable> that passes the <test>.
  • Mangler.last(<iterable>, <test>) returns the last item of <iterable> that passes the <test>.

Alternatively, you can use mangler objects to easily do multiple operations on the same set of data. They are simple object containers created and returned by the Mangler(<items>) function. On a mangler object var mg = Mangler(data), you can use the following methods:

  • mg.find(<test>) returns an array of all items in the mangler object that passes the <test>.
  • mg.first(<test>) returns the first item of the mangler object that passes the <test>.
  • mg.last(<test>) returns the last item of the mangler object that passes the <test>.
  • mg.filter(<test>) removes all items from the mangler object that doesn’t pass the <test> and returns a reference to the mangler object itself for method chaining.

I showed you in the Mangler.js introduction post how to find an item in an array by creating an index on an object property. While it is useful if you do multiple lookups on the list, for one-off searches use one of the above .first() methods, which should be more efficient. Read more ›

Share Button
Posted in Blog Tagged with: ,

Redesigning Mangler.js type handling

Mangler.js‘s type handling has undergone a major redesign which retired the flawed Mangler.getType() function and changed the type parameter on Mangler.registerType(). With the recent changes the library now supports code minification, objects built from anonymous constructors and constructors with the same name in different scopes.

Read on to see what the issue was, how it got handled, and to see the newly introduced Mangler.compareType() function for type checking.

Original implementation

Originally, Mangler.js’ type handling was based on the Mangler.getType() function, which returned a string representation of an object instance’s type:

fn.getType = function(obj) {
	var name;

	if(typeof obj === 'undefined') {
		name = 'undefined';
	} else if(obj === null) {
		name = 'null';
	} else if(typeof obj === 'object') {
		name = Object.prototype.toString.call(obj).match(/^\[object (.*)\]$/)[1];
		if(name === 'Object') {
			name = obj.constructor.toString().match(/^function ([^\(]*)\(/)[1];
			if(!name) name = '$unknown';
		}
	} else if(typeof obj === 'function') {
		name = 'function';
	} else {
		name = '$value';
	}

	return name;
}

As you can see, it extracted the type from .toString()‘s output: [object Something]. For native types it returns the type name, but for other objects it just returns a generic [object Object]. In this case I added a second step, which extracts its constructor’s function name.

The returned type string was then used to read a property from the internal types object, that contained the handler functions for cloning and iterating through the object.

When registering type handlers with Mangler.registerType(), you simply had to pass the object’s type name, matching the one returned by the above function. Read more ›

Share Button
Posted in Blog Tagged with: , ,

Iterating through JavaScript objects and arrays

In this article we’ll have a look at how to iterate through javascript objects and arrays with Mangler.js. I’ll also show you how to make your own objects iterable, and how it enhances other powerful features of the library.

Iterating through object literals and arrays

By default Mangler.js recognises 3 types of objects as iterable: object literals, arrays and mangler objects. To iterate through these objects, simply call Mangler.each() and pass a callback function in the form of callback(key, value):

var order = [
	{ product: 1, qty: 2, price: 1.00 },
	{ product: 2, qty: 1, price: 1.50 },
	{ product: 3, qty: 3, price: 2.00 }
];

var total = 0;
Mangler.each(order, function(index, item) {
	total += item.price * item.qty;
});

The callback function will be called for every key/value pair:

  • Arrays: The callback is called for every item in the array, passing the numeric item index as key and the item itself as the value.
  • Objects: The callback is called for every object property, passing the property name for the key as string and the property value.

If the callback function returns false, iteration will stop.

Recursive iteration

With Mangler.explore(), you can recursively iterate through all iterable children as well. In addition to the key and the value, the callback function gets a path and a state parameter too:

  • The path is a string containing the absolute path of the current item’s parent from the root of the iteration, e.g. root.array[0].parent.
  • The state is an optional object which is passed down the hierarchy. It is shallow copied at every level, any changes made to it are only visible to the current item’s siblings and children.

Read more ›

Share Button
Posted in Blog Tagged with: ,

Cloning JavaScript objects with Mangler.js

I was pretty busy lately watching all 5 seasons of Breaking Bad, but there were still quite a few improvements to Mangler.js since my last post. With many features taking final shape, it is time to write some posts focusing on when and how to use it, and why it might be useful.

In the introduction post I wrote a sneak-peak of how to extract parts of your data and how to create indices from object properties. I’ll get back to these topics in the future in more detail.

In this post I’ll use Mangler.js to create deep and shallow copies of objects.

Cloning (deep copy)

While many Mangler.js functions attempt to preserve references to the original data, sometimes you need an exact copy you can freely mess with without touching the original. The Mangler.clone() utility function creates and returns a deep copy of any object you pass to it:

var data = {
	id: 1,
	text: 'Hello world',
	fruit: ['apple', 'orange', 'banana'],
	now: new Date()
};

var dataClone = Mangler.clone(data);

The passed object will be processed recursively and the returned object will be an identical copy with no references pointing back to the original. Well, with one exception…

By default Mangler.js knows how to clone simple javascript objects and arrays, as well as Date objects and mangler objects. It is more than enough for processing simple JSON and literals, but if your data contains other object instances, they will not be cloned. If Mangler.js encounters an object it doesn’t recognise, it will pass its reference to the clone as is, pointing to the original object. Luckily, there is a way to teach Mangler.js how to clone other objects.

Cloning object instances

If you want to clone data that contains other native javascript types like typed arrays and Error objects, you can simply use the Mangler-natives module to add cloning support. Simply include mangler-natives.js after mangler.js to use. In case of your own types, you have to write the cloning function yourself and register it with Mangler.js:

// Define simple person object
function Person(firstname, surname) {
	this.firstname = firstname;
	this.surname = surname;
}

// Register cloning function
Mangler.registerType(Person, {
	clone: function(obj) {
		return new Person(obj.firstname, obj.surname);
	}
});

// Mangler.js can now clone person object instances
var person = new Person('John', 'Smith');
var personClone = Mangler.clone(person);

The above example creates a very simple Person object and specifies a cloning function to use. After calling .registerType(), Mangler.js will properly clone Person objects anywhere it finds it.

Standard cloning methods

In addition to a custom clone function, there are a couple of simple registration methods you can use if your object supports them.

Read more ›

Share Button
Posted in Blog Tagged with: ,

If you find something useful, please feel free to buy me a cup of coffee.