Debugging an Android app without an Android device
Many of us developers have had a sad moment when we spend good money on *cheap* Android devices that were Android 2.2 at the time when the most common devices were 1.6 or 2.1 Unfortunately, for reasons that are explained in the blog, Ansca discontinued support for devices that were not ARMv7 or above. That meant all those lovely little devices were soon redundant. If I wanted to check how my game performed and where the errors were, I could not as I no longer had an android device at my disposal.
So the first thing I did was compile and put up on the store apps for Android, this was a very bad move as I should have tested the performance, but I could not afford to get a new Android device and test. These were all in the range of $600+ and with a plan, I could not end up paying $1500-2000 over 24 months, I am already paying off my iPhone4.
Then the next time I requested someone to test my app, this was a good idea, at least I could get some real feedback of how it performed on an actual device. This was also not such a good idea, as the difference between the feedback and the expectations of feedback were large and other than the app is unusable on the android devices, there was not much that I could get. I still thank the person to have tried the app for me and spend time in testing it.
Then came a project for a client, at first it was an iPhone only app, that was cool, but when it turned to make an android version for the same, it was like hell breaking loose. I was already using a newer build that had widgets and a lot of functionality and stuff. To support Android ARMv6 processors, I had to fall back upon an old build #319. Widgets did not work, the code had to be re-written, so though one can *technically* have a single set of code for both the iOS and Android, the truth of the matter is that it is not so. After re-writing the app, it wouldn't work on the device. it crashed on start. (The device was kindly provided by the client, there are some lovely clients) Now how do I fix an app that *just* works on the iOS and after removing all traces of the widget, etc, it compiles but crashes on first run. How do I fix/debug that? I can have a series of Prints, but they cannot be seen, nor can I have alertBoxes, as they are never seen, the app crashes at start up.
So, I commented out most of the code but the crash still persisted. I was really unhappy and it had been a long time since this painful exercise had been going on. I was ready to chuck the device out and tell the client, Androids are *not* worth it. However my affinity with the platform, I started with computers in the 8-bit computers age by reverse engineering, where I would sit and spend hours listing the numbers, converting them into the OP Codes and then decompiling them to understand how it all worked. How can I quit??
So first, we'll start the panel.
this will start the control panel for configuring and starting devices. This is called the Android SDK and AVD Manager, you can update the SDK's and the AVD (Android Virtual Devices) from here.
The console is tied up as it will return to the prompt only when this window is closed, so just go back to the terminal and press ⌘+N, this will open a new Terminal window. Change to the AndroidSDK directory as last time and in this window type
at this point in time it will return / display nothing, so we need to have some devices, you can either connect a physics device and then also turn on the development mode on it, or in the AVD manager, we start a device that we create based on our device specs. I have a device called MyTestDevice that is what I need for testing my apk files. So we select that entry and click on the Start button.
The device will boot, display the Android Logo, and then boot into the GUI screen
Now if you type the command
you should see the device listed on the port opened as
If you have a physical device connected, then it will list the physical device too.
So we have a device running and connected, now we need to install the apk to the device.
The best way on the mac is to drag drop the apk file after you type the adb and press enter. It will attempt to install, if everything goes well, you will have the app installed on the device (virtual or physical as be the case) If you already had installed it earlier and are getting the error that it exists, you need to first uninstall it, you do so by typeing
this com.yourco.appname is the unique identifier that you se while compiling the app, you need this to be exactly as you set it while compiling. Once the app is uninstalled, you can just install it and it will be there.
Now you can run the app by clicking on the icon of your app, you did create the android mdpi, hdpi and ldpi icons, right? these will either show up or the default icons for android apps will show up. Starting the app will serve no purpose other than checking the performance. If you recollect we started that my app was crashing on startup, so I was trying to understand why it was crashing.
What we need to see that is the log file, and the way to see that is by invoking the command logcat
this will start up a flurry of activity, the device logs will start to flow on to this terminal. Start the app and all the print messages that you had in your app will start to show up and any errors will show up too. I found that the error was in the fact that the device was trying to access the Phone state and hence was crashing, what I had on the top of my main.lua was getdeviceID. Since I had not permitted the permissions in the build.settings the app was crashing. That was too easy...
Then I had to debug some web traffic, the console kept spewing out information of what was happening and it just kept going for me. Now debugging an app on the android was suddenly much more fun than iOS, strangely never had to debug an app on the iOS, it just worked...
so have fun debugging your app on the Android emulator...
So the first thing I did was compile and put up on the store apps for Android, this was a very bad move as I should have tested the performance, but I could not afford to get a new Android device and test. These were all in the range of $600+ and with a plan, I could not end up paying $1500-2000 over 24 months, I am already paying off my iPhone4.
Then the next time I requested someone to test my app, this was a good idea, at least I could get some real feedback of how it performed on an actual device. This was also not such a good idea, as the difference between the feedback and the expectations of feedback were large and other than the app is unusable on the android devices, there was not much that I could get. I still thank the person to have tried the app for me and spend time in testing it.
Then came a project for a client, at first it was an iPhone only app, that was cool, but when it turned to make an android version for the same, it was like hell breaking loose. I was already using a newer build that had widgets and a lot of functionality and stuff. To support Android ARMv6 processors, I had to fall back upon an old build #319. Widgets did not work, the code had to be re-written, so though one can *technically* have a single set of code for both the iOS and Android, the truth of the matter is that it is not so. After re-writing the app, it wouldn't work on the device. it crashed on start. (The device was kindly provided by the client, there are some lovely clients) Now how do I fix an app that *just* works on the iOS and after removing all traces of the widget, etc, it compiles but crashes on first run. How do I fix/debug that? I can have a series of Prints, but they cannot be seen, nor can I have alertBoxes, as they are never seen, the app crashes at start up.
The pain
The most painful part was to wait for the app to compile, then connect the android to the USB, turn on the USB mode, copy the .apk over to the Android drive, then switch off the USB, unplug the USB, uninstall the previous version, then install the new version. Start it up and *CRASH!!!!*So, I commented out most of the code but the crash still persisted. I was really unhappy and it had been a long time since this painful exercise had been going on. I was ready to chuck the device out and tell the client, Androids are *not* worth it. However my affinity with the platform, I started with computers in the 8-bit computers age by reverse engineering, where I would sit and spend hours listing the numbers, converting them into the OP Codes and then decompiling them to understand how it all worked. How can I quit??
The Plan
So the thing that came to mind was why do I not debug the app. Debug the app on the Android emulator, let me not get into telling you that on my previous Core2Duo 2.2 GHZ 15" MBP with 4GB RAM, the emulator took about 5 minutes to start up so I was not really wanting to use it, however on the iMac 27", i& QuadCore with 12GB RAM, it started in less than a minute, so it was bearable.The execution
Pay close attention as this is the crux of the whole debugging thing. All the commands you need are in this section.So first, we'll start the panel.
$> cd /(path to AndroidSDK)/ $> tools/android
this will start the control panel for configuring and starting devices. This is called the Android SDK and AVD Manager, you can update the SDK's and the AVD (Android Virtual Devices) from here.
The console is tied up as it will return to the prompt only when this window is closed, so just go back to the terminal and press ⌘+N, this will open a new Terminal window. Change to the AndroidSDK directory as last time and in this window type
$> platform-tools/adb devices
at this point in time it will return / display nothing, so we need to have some devices, you can either connect a physics device and then also turn on the development mode on it, or in the AVD manager, we start a device that we create based on our device specs. I have a device called MyTestDevice that is what I need for testing my apk files. So we select that entry and click on the Start button.
The device will boot, display the Android Logo, and then boot into the GUI screen
Now if you type the command
platform-tools/adb devices
you should see the device listed on the port opened as
emulator-5556 device
If you have a physical device connected, then it will list the physical device too.
So we have a device running and connected, now we need to install the apk to the device.
$> platform-tools/adb install (path to the apk)
The best way on the mac is to drag drop the apk file after you type the adb and press enter. It will attempt to install, if everything goes well, you will have the app installed on the device (virtual or physical as be the case) If you already had installed it earlier and are getting the error that it exists, you need to first uninstall it, you do so by typeing
$> platform-tools/adb uninstall com.yourco.appname
this com.yourco.appname is the unique identifier that you se while compiling the app, you need this to be exactly as you set it while compiling. Once the app is uninstalled, you can just install it and it will be there.
Now you can run the app by clicking on the icon of your app, you did create the android mdpi, hdpi and ldpi icons, right? these will either show up or the default icons for android apps will show up. Starting the app will serve no purpose other than checking the performance. If you recollect we started that my app was crashing on startup, so I was trying to understand why it was crashing.
What we need to see that is the log file, and the way to see that is by invoking the command logcat
$> platform-tools/adb logcat
this will start up a flurry of activity, the device logs will start to flow on to this terminal. Start the app and all the print messages that you had in your app will start to show up and any errors will show up too. I found that the error was in the fact that the device was trying to access the Phone state and hence was crashing, what I had on the top of my main.lua was getdeviceID. Since I had not permitted the permissions in the build.settings the app was crashing. That was too easy...
Then I had to debug some web traffic, the console kept spewing out information of what was happening and it just kept going for me. Now debugging an app on the android was suddenly much more fun than iOS, strangely never had to debug an app on the iOS, it just worked...
End Note
So before I end this article, a few words on this, you can create any android device that you want, add any amount of memory, add a memory card, etc. If you see the listing in the AVD manager above, you will see that I even have a Nook device. This is a wonderful way to see what is happening on your device (virtual or physical) The only painful procedure is recompiling and updating the app onto the device. For that I almost had press ^+C to kill the logcat, then type in the uninstall command, while the new apk is getting compiled, then run the install command followed by the logcat again. Everytime I wanted to get a new version, the process was just pressing the up arrow thrice and pressing enter...so have fun debugging your app on the Android emulator...
Comments
Post a Comment