|More irritations with developing for Android
||[Nov. 5th, 2011|04:32 pm]
I'm nearing completion of my port of FlightPredictor for Android. While things aren't as bad as they seemed when I started learning Android development and I'm able to make progress at a reasonable rate, two things popped up over the last few days:
- One of the activities in the app is choosing an airport. There are more than 900 to choose from, so I put them in a big list with a TextView on top so you can type to filter. On the emulator, filtering is very very slow (it takes around 5 seconds from typing something until the results change), and while it won't be that slow on an actual device (please?), it will probably be noticeable. So I wanted to put up a loading indicator that goes away when it's done.
Calling the filter to do its filter-y thing is pretty simple, something like
adapter.getFilter().filter(s);where s is the string that's in the TextView. And you can pass another parameter to get a callback when a filtering operation is done.
But! If the user types in something like "bwi" in rapid succession, it will immediately try to filter on "b". (I tried to fix this problem for a while: the Filter class even has a setDelayer() method that does exactly what I want, but it's hidden...) While that's going on and the "w" is pressed, I call to filter "bw", and assuming the first request is still going on when "i" is pressed, I call to filter "bwi". When the "b" filtering is done, the filter (intelligently) then goes on to just filter "bwi". So this means I only get two callbacks that filtering has been done. So I have to essentially write a tiny state machine to keep track of, when I do a request whether there's one already pending, and if I've already done another one when there's one already pending.
I will agree that the code didn't take that long to write - most of the time was spent looking for some easier way because someone must have wanted to do this before, right? But no luck...
- FlightPredictor includes a bunch of maps of airport terminals. These are saved as image files, and there's around 20 MB worth of them. Unfortunately, as best I can tell, some (many? most?) Android phones ship with very limited space on the device itself, but come with a big SD card to store stuff on. (this is the case on David's Galaxy S phone, anyway) You can tell apps to install on the SD card, but this won't work in my case because I have a Service that runs in the background (to update flights), and you aren't supposed to let those kinds of apps install on an SD card because apparently any SD card apps get killed when the phone gets plugged in.
What I really want is to just keep the image files (stored in assets/) on the SD card, but as far as I can tell there's no way to do this. My options seem to be:
* Take the images out of the main app and make them a separate app that users would have to download. This is a terrible user experience.
* Take the images out of the main app and, the first time it's run, add logic for downloading the images and saving them to the SD card. This is what I'll have to do, I guess, but it's quite irritating to have to write and test all this extra code to work around limitations in the OS...