We recently had the pleasure of posting an update to one of our apps - Bubble Zing - on to a couple Android markets. Everything looked great on the development side and everything was pretty much tested and ready to go, so we exported our apk in Eclipse and sent it out!
Then the problems started trickling in (of course).
This was quite baffling that the same code running in Eclipse was completely breaking when running from an exported/signed APK file. What was going on here?! I googled around for various errors and almost all of them talked about missing libraries and such. Well, none of those things were my issue.
I finally started getting some useful information from logcat about ClassNotFound and being unable to get new instances of *my activity* or various other failures about FindClass failing.
I was pretty stumped by the whole thing, so I ended up opening the APK like a zip file to check out what was actually IN the apk. Everything looked as it should have been. All my resources were there, the class path stuff was set as well (really confusing me why all this classnotfound stuff was happening now). It wasn't until I ran apktool on my apk to get some actual additional information about my java files that I started to trace down the issue. I noticed that all of my Java classes which were called from my native library were named "a.java" and "b.java", etc. As opposed to all the normal java files which were not interacting my native shared library were fine. So, it seems like we narrowed down what sort of thing was happening here.
Ok, somewhere in the export process, I was was losing my actual java names... and with things like fully-qualified names everywhere, I suspect this was a major problem.
So, I found that Proguard was obfuscating away my class names during the export process, meaning once my app was in apk form, calls from native code were completely unable to find half of what it needed to talk to for it to work!
For those interested, I added the following lines to proguard.cfg to inform proguard that I would like to keep most of my stuff unmangled please:
-keep public class [FULLY.QUALIFIED.PACKAGE.NAME].* {
public static *;
public static *;
private static *;
}
For us, only static methods were being called from native code. We also set *all* of our classes in our package to be saved with the "-keep public class" line.
In retrospect, this totally makes sense, since during the apk packaging process, it realized that at no point were some of my chunks of java code being called by any other java code, so proguard figured it was ok to munge those up in to various cryptic alternate symbols. I suppose it wasn't proguard's fault, but really my own misunderstanding of how the export process works and what proguard did for you automatically (or why).
I'm glad that was over, lesson learned?! Always test an APK on my devices BEFORE sending it out to the market, even if we completely ran through all our tests before the export process.
Technical blog posts about programming, graphics, technology, animation, games, maybe some politics or game reviews.
Showing posts with label eclipse. Show all posts
Showing posts with label eclipse. Show all posts
Thursday, May 31, 2012
Wednesday, February 15, 2012
Design to Product on Android - OMG Code, well almost! (9 / 17)
Ok, finally, we're talking about the core of app development, the coding!
First, I must emphasize that it is probably in your best interest to consider using an app library, or writing your own. This will substantially cut down on the time needed to make a game (or probably any app for that matter). Of course the trade off is learning the external library, figuring out its limitations, and making new products with it, which translates to more initial time involvement, but could pay out in the end.
As for us, we developed a small game library that has some very basic code all wrapped up in to a tiny, neat package. It mostly allows us to mangle with time functions, "button" code, random numbers, and some other graphical utility functions (like getting the current display orientation, the density of the screen, the screen dimensions, etc).
If you make your own library, like we did, I highly recommend putting any and all code that you think is generic enough that *all* projects of yours in the future could want.
If you didn't already know, you will have to have some way of writing code. We recommend using Eclipse with the Android SDK, it's free, works, and packs various useful conveniences while developing. You will also need someone versed in Java and able to use the Android SDK.
If your person doing the development is new to Android, Java, or both, we highly recommend making some test projects first, before attempting to make your dream game/app.
It is our intention for this to not be a tutorial on how to make an app in detail, but rather talk about designs and coding specifics instead, more or less from a management perspective/process.
Ok, so once we have our IDE all set up, we can look over our game design and start plotting how we want to design the software itself.
Different software process methodologies deviate greatly in this area, our studio essentially identifies major topics/nouns used in the design of the product and USUALLY makes an assumption that those will be Java classes. I mentioned *usually* because this isn't always the case and we also do not use any automated tools or UML or anything goofy like that.
Instead, we look at the major concepts of the design and turn those in to classes first. Specifically, we know that we will need a PlayingField where by all "game playing" will take place. That becomes a class (and a very useful one at that).
Because of how Android works, we must have an Activity class. From there, we also must have our own SurfaceView class (we implement a GameView class that inherits from SurfaceView), and a class which encapsulates the main processing of the game. We make a GameThread class that inherits from Thread so that all our game processing can take place on its own.
So, without really getting in to picking apart our design, we know we have the following classes already:
GameActivity
GameView
GameThread
PlayingField
While we pick apart our design and start coding, the blog will be inactive for the next couple of days.
First, I must emphasize that it is probably in your best interest to consider using an app library, or writing your own. This will substantially cut down on the time needed to make a game (or probably any app for that matter). Of course the trade off is learning the external library, figuring out its limitations, and making new products with it, which translates to more initial time involvement, but could pay out in the end.
As for us, we developed a small game library that has some very basic code all wrapped up in to a tiny, neat package. It mostly allows us to mangle with time functions, "button" code, random numbers, and some other graphical utility functions (like getting the current display orientation, the density of the screen, the screen dimensions, etc).
If you make your own library, like we did, I highly recommend putting any and all code that you think is generic enough that *all* projects of yours in the future could want.
If you didn't already know, you will have to have some way of writing code. We recommend using Eclipse with the Android SDK, it's free, works, and packs various useful conveniences while developing. You will also need someone versed in Java and able to use the Android SDK.
If your person doing the development is new to Android, Java, or both, we highly recommend making some test projects first, before attempting to make your dream game/app.
It is our intention for this to not be a tutorial on how to make an app in detail, but rather talk about designs and coding specifics instead, more or less from a management perspective/process.
Ok, so once we have our IDE all set up, we can look over our game design and start plotting how we want to design the software itself.
Different software process methodologies deviate greatly in this area, our studio essentially identifies major topics/nouns used in the design of the product and USUALLY makes an assumption that those will be Java classes. I mentioned *usually* because this isn't always the case and we also do not use any automated tools or UML or anything goofy like that.
Instead, we look at the major concepts of the design and turn those in to classes first. Specifically, we know that we will need a PlayingField where by all "game playing" will take place. That becomes a class (and a very useful one at that).
Because of how Android works, we must have an Activity class. From there, we also must have our own SurfaceView class (we implement a GameView class that inherits from SurfaceView), and a class which encapsulates the main processing of the game. We make a GameThread class that inherits from Thread so that all our game processing can take place on its own.
So, without really getting in to picking apart our design, we know we have the following classes already:
GameActivity
GameView
GameThread
PlayingField
While we pick apart our design and start coding, the blog will be inactive for the next couple of days.
Subscribe to:
Posts (Atom)