Bill Atkinson came up with the idea of defining a system flag called "MonkeyLives" (pronounced with a short "i" but often mispronounced with a long one), that indicated when the Monkey was running. The flag allowed MacPaint and other applications to test for the presence of the Monkey and disable the quit command while it was running, as well as other areas they wanted the Monkey to avoid. This allowed the Monkey to run all night, or even longer, driving the application through every possible situation.
Android docs are pretty terrible anyway. Have fun finding out what a 'Looper' is for or how it even works without using stack overflow. Then be amazed and horrified.
And then there are gems like WiFiManager.getScanResults(), which according to the docs returns a List<ScanResult>. Except that it's actually implemented as
So actually it returns a list except sometimes it returns null, which I have seen happen and it caused my app to force-close. There's shit like this all over the place. No wonder so many apps crash on random devices.
So now any time I want to call a piece of the Android API I haven't worked with before I have to go find the source to make sure it's not doing something unexpected because I can't trust these Google monkeys to properly document their stuff. Sigh.
You'd be able to implement that as a Maybe [WifiResult], maybe Just a list of wifiresults or maybe Nothing, copying directly, but you'd probably want to have your datatype be Either String [WifiResult], either you get on the Left an error string or on the Right the list of wifiresults.
And more importantly, if a function has [WifiResult] as the defined return type, you can be absolutely definitely sure that you get a list back.
This is not something inherently unique to Haskell. Any strictly typed language could easily have chosen to not let null be a member of all classes. Or at the very least add some "non-nullable" qualifier to types.
All this is discoverable in static code analysis. It is entirely possible to make tools that check the docs cover all these cases. There are probably tools they can buy to do it.
> Have fun finding out what a 'Looper' is for or how it even works without using stack overflow. Then be amazed and horrified.
What is the problem with Looper? Looking at Looper.java and MessageQueue.java, the code is ugly but the only questionable parts seem to be MessageQueue's recycling of Message objects..
Well the documentation is very scarce, not just in the Looper class itself, but also in places where you mysteriously need one (i.e. LocationManager.requestLocationUpdates). I really don't get the point of the Looper class anyway, as (better) facilities to do stuff in separate threads already exist in the standard Java class libraries (i.e. Executor and ThreadPool come to mind which both work fine on Android). I also don't see why I should bring my own thread just to catch an event, you'd think the class library could do that for me? My main problem here is the lack of clear documentation explaining why I need this non-standard not-invented-here syndrome piece of crap. Compare this to the Executor class' documentation from the standard Java libs for example.
Then there's the way in which the constructor of the Handler class will automatically attach to the 'current' looper thread. If the current thread is not a looper, it will throw a RuntimeException. It would probably be appropriate here to create one's own Exception class rather than throw a generic one both for readability of the stacktrace and so you can catch it explicitly. To me is just another example of amateuristic/lazy software engineering and lack of understanding of general Java principles. Either way, this automatic association is not explained in the documentation of Looper, they just give the example and you're supposed to understand what's happening. I don't see what would be wrong with just creating a Handler and attaching it to the looper thread explicitly, if not just for readability's sake. My main gripe here is the lack of documentation, as if they really don't give a crap about whether or not you understand what you're doing, as long as you're copy/pasting their example you should be fine.
The naming is confusing. What the fuck is a 'Looper'? This name only makes sense if you're coming from C and I guess I'm old enough to get it, but come on people, there must be more descriptive names than that. Why am I posting messages to the Handler object? Isn't the looper thread supposed to post messages to the handler, which then 'handles' them? Do you post an event to an event handler? Why can't the functionality of Looper and Handler just be in one class? What's the use of the CallBack interface, if I can just extend Handler? In both cases I need to implement only a single method, so what's the point?
According to the docs this is the functionality of the Handler class:
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
Here's how Swing lets you do stuff in Swing's main UI thread:
Lol, funny fact is that I have been collaborating with dpkg team in Debian and they created an identical function in C to report ANY error condition. I've read a lot of //D'OH and //ROFLMAO comments in rhythmbox source code so I guess this is pretty common over open source devs within the Linux community!
instead of cutesy shit like that, how about documenting stuff like customizing input methods. the SoftKeyboard sample doesn't have a single usage datum online. I, ahem, googled it. How do I enable a custom keyboard for just one text entry widget?
oops, didnt mean to interrupt the cute fest with actual question. fucking morons.