RTFM

Going back to re-scan the Android dev guide now that I understand a bit better what’s going on. It makes a lot more sense now.

First I had a look at binding list views to data. This bit of code had some nuggets:

ArrayAdapter adapter = ArrayAdapter.createFromResource(
   
this, R.array.colors, android.R.layout.simple_spinner_item);
adapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

My code was similar, except the setDropDownViewResource call was commented out because the method was unavailable when I tried it; looking more closely I saw that I’d set adapter to type SpinnerAdapter – which is just an interface without the actual methods of an actual Adapter; wonder where I got that from? Correct typing allowed me to use the method. I had not noticed before that there were prefab views available for the spinner; oddly, however, using these resulted in invisible text and strange buttons on the dropdown:

(And, just now noticing that ScribeFire isn’t inserting an image intuitively. Bleh. Not that WordPress hasn’t given me “shaking fist syndrome” from trying to insert images too.)

Also discovered notifyDataSetChanged() which keeps me from having to create a new cursor and adapter when I know or suspect the data for the view has changed. I guess that’s one of the benefits of Activity cursor management? Just requires retrieval and careful casting of the adapter to call the method. Going to try it now. In my case, with a custom adapter (subclassing SimpleCursorAdapter), it looks like so for my ListActivity:
    ((EventCursorAdapter) getListAdapter()).notifyDataSetChanged();
Well, that does not in fact re-run the query and get the new data. So that’s a bit misleading. But it DOES seem to work for my spinner:
    ((SimpleCursorAdapter) mSpinner.getAdapter()).notifyDataSetChanged();
Hmm… what’s the difference? Stack Overflow has someone recommending futzing with the cursor directly on the ListActivity though the next response indicates notifyDataSetChanged should work. Comments on this ListActivity tutorial indicate some puzzlement about the issue as well. A response here indicates it should work.

It looks like SimpleCursorAdapter gets its notifyDataSetChanged method from BaseAdapter, which probably does nothing but update the view as no query logic could be involved. That doesn’t explain why there’s different behavior between a Spinner and ListActivity which both use SimpeCursorAdapters, but it suggests I can try overriding the method in my custom adapter and requerying the cursor.
    @Override
    public void notifyDataSetChanged() {
        getCursor().requery();
        super.notifyDataSetChanged();
    }

Ooh! Bad idea! Apparently the requery causes notifyDataSetChanged to be called and it recurses into a stack overflow. I can add a separate method to try the same thing, though. And… that works – and the cursor requery automatically kicks off the notify and redraw.

I must be missing something. I don’t understand why I’d need to explicitly requery in the case of an adapter for ListActivity and only need to notify for a Spinner.

Advertisements

wordpress <pre> borkage

Sometimes WP doesn’t seem to keep the formatting I put on code. It should all be rendered as <pre> but sometimes it’s changed when I go to edit an article (as inevitably I do, it seems). It remains monotype but the <pre> is gone and formatting is wonky – generally everything is smashed to the left. I think it’s WP itself doing this, although it may be that posting via ScribeFire sets it up for this to happen. Maybe it’s related to tabs not pasting well into the web form. I’ll try to keep the formatting correct, just thought I’d point out what’s happening if I miss something.

Also it looks like WP doesn’t escape HTML I put in the title. Interesting, that.

unit testing android

Trying out ScribeFire for blogging, looks decent (and is a plugin for FireFox so cross-platform). So far looks nice.

Looking at Diego Torres Milano’s blog: Android: Testing on the Android platform – Unit tests – obviously this is over a year old and out of date (1.0 was current then). When creating a project now the ADT plugin allows you to create a parallel test project at the same time or a later time. I somehow picked out the right way to run a simple unit test once, but it doesn’t seem to want to run again. And when running as an “Android unit test” it actually opens an emulator in order to do unit tests?!? I can kind of understand that but it seems unnecessary for unit testing. For now, writing this off as too out of date.

Continuing with Diego Torres Milano’s blog: Android: Testing on the Android platform – ApiDemos tests. I followed the directions – I think – but when I pasted the source files into the test project they got pasted in the original package locations (e.g. com.example.android.apis not com.example.android.apis.test), which seemed to cause no problems. Linking the test project to the original was as advertised. Directions are ambiguous as to which manifest file to copy to the test project – get the one from the test directory. I was able to run the ApiDemosTests package as an Android Junit Test and see it actually go; did not have to do anything in the emulator, and the results show up in the JUnit widget in eclipse. I could see things happening in the emulator, so I guess it makes sense to have it up :-) I also tried running them from the Dev Tools or from adb and that worked as specified. Good to know.

Diego didn’t label this post so I almost missed it: Diego Torres Milano’s blog: Android: Testing on the Android platform – Creating tests; and this is a pretty good starting point. Got my test suite runner and a unit test shell set up, going to have to stop here for now.

So it’s great to see that this guy is also a bit frustrated with the docs (mostly, lack thereof) on testing; like emulator skins, tests are provided for you to reverse engineer, but not explained anywhere. I guess working tests are a little better than actual documentation which can get out of date fast. Diego seems to have a good understanding of JUnit and testing before coming to Android, which helps him. I don’t have that, but my brother does; this seems like an area that’s ripe for exploration and making a name by explaining. Heck, it would probably be worthwhile just to provide links to selected relevant posts by Diego putting them in an order that would be helpful to a beginner learning this stuff.

At my last meetup I told people that after you create an AVD, the tool doesn’t provide you any way to change its configuration. This is true, but you can edit the files that specify the config pretty easily – they aren’t even XML. The question is whether the emulator image itself (in the user’s .android directory) is modified at all according to config. I suspect the answer is “no.” At least, I tried changing the skin on an AVD (edit config.ini within the .avd definition) with no adverse consequences. But that’s superficial; other elements that refer to actual capabilities might need a matching setting inside the emulator image. I don’t know yet.