Google+ Badge

Wednesday, July 20, 2011

Android conversion continues

I continue to pound away on my Android conversion of the iPhone app I am close to finishing up. I have been working with SQLite on both sides. The wrappers are different which hosed me over for a bit today.

iPhone
[database beginTransaction]
... db operations
[database commit]

Android - WRONG
database.beginTransaction();
   ... db operations
database.endTransaction();

Android - CORRECT

database.beginTransaction();
   ... db operations
database.setTransactionSuccessful();
database.endTransaction();


Yes, you need to begin and end but you MUST call setTransactionSuccessful or kiss all the operations goodbye.

I added a new call to the current XML Pull Parser we are using on the Android side. It allows you to send in a callback to get each row of data as it is processed. For our big boy Java app we just parse everything into memory then write from memory structure to DB table. Not a good idea on a mobile device as I discovered on the iPhone. I use the basic NSXMLParser there and build one record at a time into a NSDictionary. I added a bit of logic into our Pull Parser for the Android allowing a callback interface with a Map of values for each record. Saves a ton of memory and time under each OS. I was very happy how easy it was to do that conversion. I have begun my testing using the largest table I download so far, it has 17,401 records.

Timings
iPhone Simulator   3.7 seconds
iTouch Rev3       42.7 seconds


Android Emulator  41.0 seconds
Samsung Galaxy S  11.8 seconds

As you can see the iPhone simulator can really fool you into thinking your code is running great. On the Android side the emulator forces you to code tighter and the phone gives you a nice speed break. I am not at all happy with the 42.7 seconds it takes the iTouch to parse and store the data. Not sure what I can do to fix it but I will have to play around with it more soon.

Luckily we only need to download the big tables when they are stale, which it will be once a year. I get a list of tables and last update date / times from the server on login. I compare my local last update to the server and grab a newer copy if it is out of date. We also have session tables that I have to load post login every time but I only want to do that once a session so I have all kinds of fun logic to decide if a table is stale. Seems to be working on the iPhone so I will start on that conversion next.

I really wish the Android device emulator ran faster. Total switch from the iPhone. iPhone the simulator is very fast. Of course the simulator is using same OS as the MacBook Pro so it really has a lot less to do. On my PC the emulator has to emulate a Linux type OS and the device. It is much faster to run on Android the actual device but of course that is a pain in other ways in that I have to type my password on the silly thing over and over.

The debugger is much slower under Android too. It is more usable as I can just click on variables and see their values or highlight a section of code and do an Inspect to see the value. Typing in commands to GDB on the Mac sucks and if you want to see some UTF8 text you have to type in a long command to convert it into something usable. Don't miss that at all.

Command to convert UTF8 NSData block to NSString in Xcode
po [NSString stringWithUTF8String:(char *)[data bytes]]

Pretty simple to tag my debug output strings and filter them via LogCat. DDMS lets me look at the file system of the emulator with ease but I have to copy my DB to my local HD browse it. Much easier to use SQLite Manager under Firefox on the Mac to look into the simple, but buried rather deep, directory structure of the simulator on the Mac to grab the .DB file and check it out.

I thought some things would be more straight forward to port especially since I was using SQLite on both devices but the wrapper classes are just different enough to cause confusion. Once I get in the base calls in my helper areas I will not even have to think about it.

Just as I expected most of the code is a lot shorter on the Android side.

  • Not dealing with both a H and M file cleans up what you have to see in the code directory. Calls are less wordy as you are not naming parameters. 
  • Much easier to set up static variables and enums are really enums and not globals. 
  • Date processing is so much easier I am able to in-line the code as it is a few lines where Objective C was too many lines so I put things in separate methods. 
  • You can fully qualify what you are putting in a Map so I don't have to typecast things. 
  • No matched alloc / release pairs or autorelease calls on end of temp variables
Other random things
  • SVN interaction works in Eclipse but caused me numerous issues in Xcode. 
  • I can keep test.jpage open in Eclipse to run small code snippets to make sure I am doing substring correctly and the like. 
  • Editor tabs are not randomly reused when I am using the debugger
  • If I double click on a file to open it or a search result is in an already open that tab opens instead of reusing the tab I happen to be on (tab support in Xcode is just barely acceptable)
  • Auto comment generation for JavaDoc is very handy
A lot more to do but it is moving on a pretty decent clip. So far I am just on the behind the scenes processing but soon I will be dealing more on the UI side and I will have to make some changes as there are areas easier to code on iPhone due to its one resolution for all devices. I need to find a nice tiled background for the Android. Currently using one that is OK but could be more professional. For the iPhone I had two images, one portrait and one landscape but that image shows seams when you tile.