Ludicrous Software

Remove Unused Libraries From Corona Apps

Ansca has incorporated a lot of libraries into the Corona SDK that make it very easy to add social, analytics, and other features to your app. The downside is that all these great features are still bundled into your app during the build process, even if you don’t use them. Ideally, Corona would exclude these unused libraries, but currently it does not. However, if you’re building for Android, it’s possible to remove them from the apk file.

Doing so will trim approximately 2.5 MB from the file, which is a pretty substantial savings.

(Update: it turns out that the bulk of the savings comes from simply rebuilding the apk file using the tools in the SDK. This was pointed out by a commenter in a thread on Ansca’s forums. So I tried it with Poker Solitaire. Simple repackaging the apk decreased the total size by about 2.1 MB, so it turns out that the libraries actually take up a pretty small proportion of the apk. So if you’re at all leery about deleting libraries from your app, you can simple rebuild the app and still reap a substantial reduction in file size!)

It can also help you reassure clients who may wonder why all this extraneous stuff is being included in their app (I have had to answer this question for enterprise clients who are using Corona-built apps internally). To recoup this space, there are a few prerequisites:

  1. You need to have the Android SDK installed;
  2. You need to have the Java JDK installed;
  3. You need to be at least somewhat comfortable with the command line.

I’ve tested this in OS X using builds of both my own apps and client apps. I see no reason why it wouldn’t work in Windows, but I haven’t tested it. The resulting apps have installed and worked fine for me in all cases, but please bear in mind that you’re doing this at your own risk and I’m not responsible for anything at all that you care to do with the following information. So let’s get started:

First Things First

You need an apk generated by Corona, so build your app as you normally would.

Next, open up Terminal.app and navigate to the directory containing your apk file. The apk is essentially a zip archive, so you could simply change the extension and unzip it. If you do this and examine the results, you’ll notice that the manifest file is in a binary format - this is done as part of the build process. Since we need to edit that file, we need it in plain text. Instead of simply unzipping the file, we’re going to use apktool, which is part of the Android SDK, to ‘decode’ the apk file. Enter this at the command line - I’m using my Poker Solitaire game in this example, so obviously replace that with the name of your apk file as you follow along - and you should see the resulting output:

1
2
3
4
5
6
7
8
9
10
11
$ apktool d PokerSolitaire.apk
I: Baksmaling...
I: Loading resource table...
W: Skipping "android" package group
I: Loaded.
I: Loading resource table from file: /Users/darren/apktool/framework/1.apk
I: Loaded.
I: Decoding file-resources...
I: Decoding values*/* XMLs...
I: Done.
I: Copying assets and libs...

If apktool isn’t in your path, you’ll need to enter the full path, which will look something like this:

1
$ \path\to\AndroidSDK\platform-tools\apktool

This will create a directory called ‘PokerSolitaire’, which will contain the following files and directories:

The first thing to do is open up the AndroidManifest.xml file in your favourite text editor and remove some entries. Basically, you need to remove anything that looks like it’s related to Papaya Mobile, Open Feint, or Super Rewards. These will be entries where the android:name attribute starts with com.papaya, com.openfeint, or com.adknowledge. Here are a few by way of example - this is not an exhaustive list:

1
2
3
<activity android:theme="@style/OFNestedWindow" android:label="NativeBrowser" android:name="com.openfeint.internal.ui.NativeBrowser" android:configChanges="keyboardHidden|orientation" />
<provider android:name="com.papaya.social.PPYSocialContentProvider" android:authorities="com.ludicroussoftware.test.PokerSolitaire.ppy_cache" />
<activity android:name="com.adknowledge.superrewards.ui.activities.SRPaymentMethodsActivity" android:screenOrientation="portrait" />

You can also delete any entries that start with com.zong. I haven’t actually investigated what these do - they seem to be related to Super Rewards - but I was able to safely delete them. Once you’ve got them all, save the file.

Next, we’ll delete the actual libraries. Expand the smali\com directory, and you should see something like the screenshot above. Delete directories for any libraries that you’re not using. Poker Solitaire uses none of these, so I was able to safely delete the adknowledge, facebook, flurry, inmobi, inneractive, openfeint, papaya, and zong directories. I also deleted the zongfuscated directory with no ill effects. Obviously, if you are using any of these services, do not delete them.

Rebuild the apk

Back in the Terminal, here’s what you need to do:

1. Build the apk file using apktool:

1
2
3
4
5
6
7
8
Behemoth:Desktop darren$ apktool b PokerSolitaire PokerSolUnsigned.apk
I: Checking whether sources has changed...
I: Smaling...
W: Unknown file type, ignoring: PokerSolitaire/smali/.DS_Store
I: Checking whether resources has changed...
I: Building resources...
I: Copying libs...
I: Building apk file...

2. Sign the apk using the jarsigner tool that’s part of the Java JDK. You’ll also need your keystore and key alias that you used to sign the app, as well as the password. The key alias is the last argument passed to jarsigner:

1
2
Behemoth:Desktop darren$ jarsigner -verbose -keystore ~/Dropbox/LudicrousRelease.keystore ~/Desktop/PokerSolUnsigned.apk ludicrousRelease
Enter Passphrase for keystore: 

After you enter your passphrase, you’ll see a whole bunch of ‘signing:’ messages zoom by; once it’s all done, you have a signed apk file.

3. The last step is to zipalign the apk file:

1
Behemoth:Desktop darren$ zipalign -v 4 PokerSolUnsigned.apk PokerSol.apk

And you’re all done. You can test your app as you normally would, upload the Android Market, etc.

But Wait, There’s More!

If you poke around in the directory created by apktool, you’ll notice a bunch of other files related to Papaya and Open Feint, mainly. There are all kinds of image files in the res directory, as well as a bunch of entries in the various xml files in res/values. I tried going for a wholesale removal of all of these things, which resulted in the build process breaking. I haven’t yet figured out why that’s happening. The completist in me would like to figure it out, but these images add up to a small percentage of the total space taken up by all of these libraries, so it’s not a huge deal if they’re left in the app. It’s bothersome, but at a certain point the law of diminishing returns kicks in and I just need to Let It Go.