Thursday, October 12, 2017

Posting Again?

Things got a little busy after my last post.  And now it's almost five years later!  Wow.  In that time I moved into iOS development in Objective-C, then Swift.   Last year I abandoned mobile altogether, returning to enterprise systems in Java 8 (sadly.)  There are so many things that I should have posted in these past five years, but just didn't have the time or inclination.  Since the whole point of this blog is not for others to read, but for myself to remember how I solved certain problems, and to help the learning process by explaining things, I suspect I might end up regretting not having posted anything.

Anyway, I think I might take up posting again.  Especially since I have returned to tinkering with Haskell.  There will be lots of stuff to talk about.  Also, there are a few TDD and Java 8 topics on which I might pontificate, just to vent.

Wednesday, January 23, 2013

Leaking Activities

Important safety tip.  If a method or constructor requires a Context, don't pass it an Activity.  It works, but it's too dangerous.  It's just too easy to leak the activity.  Better to do activity.getApplicationContext().

Corollary:  Follow this rule except when you can't.  :-)  It turns out that if the code that requires the Context reference needs to start an activity, you'll get an exception if it doesn't set the FLAG_ACTIVITY_NEW_TASK flag in the Intent:

java.lang.RuntimeException: Unable to start activity ... Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.  Is this really what you want?




Wednesday, November 21, 2012

Button in ListView

Many thanks to Adam Toennis who directed me to this stack overflow post that helped resolve an ugly problem.  I'm posting it here so that when I run into this again in 6 months, I can find it easily.

Problem was that we put a button in a list view row.  We obviously want the user to be able to tap the button, but we still wanted the user to tap the row itself too.  Just putting the button in clobbered the row tap.

Answer came from this post: http://stackoverflow.com/questions/3045872/listview-and-buttons-inside-listview

In short,  put android:focusable="false" in the button element.



Monday, March 5, 2012

Ruby, SOAP, and XML Attributes

If you're looking to interface with a SOAP web service from a mobile device -- especially Android -- don't.  The best SOAP library I could find for Android was ksoap2, and it is way to fringe for comfort.

We decided that it would be best to write a RESTful service facade to front the SOAP service instead.  Trying to flesh it out quickly, I turned to Ruby with soap4r, whereupon I ran smack into a problem that took me a few days to track down the resolution to.

The soap request needed to look something like this:

    

Simple, right? Well the hard part is the attribute.  WSDLDriverFactory is not well documented.  Actually, I don't think it is documented at all, but I found examples on the web of how to use it.  You pass your soap method a map of the values, like this:
{:rootElement => {:childElement => {:myId => "123456"}}}
That works great if "myId" is an element contained by childElement, but in our case it's an attribute.  How do you tell the proxy that myId is the value of an attribute, not the valude of an element? You would think that it would be smart enough to figure it out, but it's not. After digging around for hours, I finally found an obscure reference to the answer: you have to prefix the attribute name with "xmlattr_". So the correct map looks like this:
{:rootElement => {:childElement => {:xmlattr_myId => "123456"}}}
The full code looks like:
require 'soap/wsdlDriver'

wsdl = 'http://host:port/some-service?WSDL'

client = SOAP::WSDLDriverFactory.new( wsdl ).create_rpc_driver
client.wiredump_dev = $stdout
client.options["protocol.http.basic_auth"] << [wsdl, 'MY_USER', 'MY_PASSWORD']
result = client.doSomething(
{:rootElement =>
  {:childElement => {:xmlattr_myId => "123456"}}})



Wednesday, December 7, 2011

Custom View Drawing in Android with Infinite Recursion

Nice title, eh?  No, it's not something you want to do, but it's something easy to do if you take a shortcut.

In View.onDraw, you might be tempted to call this.setBackgroundDrawable, or this.setBackgroundColor like this:
 @Override
 protected void onDraw(Canvas canvas) {
          if (image) {
            setBackgroundDrawable(d);
          } else {
            setBackgroundColor(0xffffffff);
          }
 }

That's a bad idea.  These calls result in a recursive call to your onDraw method (although the Android javadocs don't seem to say so).  You might not notice at first, or at all, until one day something draws attention to the fact that your view is furiously drawing itself repeatedly forever.

The solution is to use the Canvas and Drawable methods that do the same things. It's just as easy, and you'll avoid the unwanted recursion.
 @Override
 protected void onDraw(Canvas canvas) {
          if (image) {
            d.draw(canvas)
          } else {
            canvas.drawColor(0xffffffff);
          }
 }

Monday, November 14, 2011

Resources NotFoundException in Android

Sometimes (ok frequently) I do stupid things.  Here was my offending line:

list.setAdapter(new ArrayAdapter<Foo>(this, android.R.id.text1, foos));

Which was met at runtime by this stack trace:

android.content.res.Resources$NotFoundException: File  from xml type layout resource ID #0x1020014
at android.content.res.Resources.loadXmlResourceParser(Resources.java:1916)
at android.content.res.Resources.loadXmlResourceParser(Resources.java:1871) 
at android.content.res.Resources.getLayout(Resources.java:731)
at android.view.LayoutInflater.inflate(LayoutInflater.java:318)
   

Not sure what I was smokin when I wrote the code.  Was in a hurry.  Problem is with the android.R.id.text1.  The parameter is supposed to be a layout, not an id.

Correct code is something like:


list.setAdapter(
   new ArrayAdapter<Foo>(this, android.R.layout.simple_list_item_1, foos));

Or whatever layout you like.  

This problem was a little obscure because I was just trying to do something very quickly and didn't have any exception handling in place.  Additionally, none of my code appeared in the stack trace.

Since it's not obvious from the stack trace what the problem is, I've posted it here.  I tend to do the same stupid things at approximately 6-month intervals :-)

 




Monday, November 7, 2011

What? Sorry, I missed that.

With all the great stuff that phones do today, why do we have to endure such poor sound quality for phone calls? Please, device makers, fix this problem! I'm tired of struggling to make out what people are saying on the phone. Yeah, yeah, you've only got so much space to work with, but figure it out! It's not that it can't be done. It's that I don't think anybody cares to do it. Anyone else want to make some noise about this?