Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker
Joe Moore

Fast Android Debugging with IntelliJ

Joe Moore
Friday, July 15, 2011

Sure, you can launch your Android app in IntelliJ’s debugger, but that’s slow. IntelliJ allows you to dynamically attach the debugger to a running device using the “Attach debugger to Android process” button. That’s fast!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Android Tidbits 6/23/2011: Tabs and Colors

Joe Moore
Thursday, June 23, 2011

Pivotal Android Tabs

We have published a simple Android project that illustrates how to use tabs in an Android app: TabActivity, TabHost, TabWidget, and android:divider. Thank you Pivot Ryan, the original author, for taking the time to write and open source this. Check it out, fork it, and enjoy — https://github.com/pivotal/Pivotal-Android-Tabs

Tabs 1

Tabs 2

See Hex’d Colors

IntelliJ trick: in a colors.xml file, place your cursor on a hex value and hold down Shift. You’ll see a large preview of the color.

Hex colors in IntelliJ

Colors and States

(Repost from the 6/22/2011 Standup blog): You can use a selector drawable to set Android text color for the various states (focused, selected, etc.) using a drawable xml file. IntelliJ will complain and say this is invalid syntax but the application will use the file as you would expect. This only seems to work for the android:textColor attribute in TextViews.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Android Tidbits 6/22/2011: Hiding Header Views

Joe Moore
Wednesday, June 22, 2011

Android ListView#addHeaderView and ListView#addFooterView methods are strange: you have to add the header and footer Views before you set the ListView‘s adapter so the ListView can take the headers and footers into consideration — you get an exception otherwise. Here we add a ProgressBar (spinner) as the headerView:

// spinner is a ProgressBar
listView.addHeaderView(spinner);

We’d like to be able to show and hide that spinner at will, but removing it outright is dangerous because we’d never be able to add it again without destroying the ListView — remember, we can’t addHeaderView after we’ve it’s adapter:

listView.removeHeaderView(spinner); //dangerous!

So let’s hide it! Turns out that’s hard, too. Just hiding the spinner view itself results in an empty, but still visible, header area.


Now try to hide the spinner:

spinner.setVisibility(View.GONE);

Result: header area still visible with an ugly space:



The solution is to put the progress bar in a LinearLayout that wraps it’s content, and hiding the content. That way the wrapping LinearLayout will collapse when its content is hidden, resulting in a headerView that is technically still present, but 0dip high:

  <LinearLayout
      xmlns:a="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content">
    <!-- simplified -->
      <ProgressBar
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
  </LinearLayout>

Then, set the layout as the header:

spinnerLayout = getLayoutInflater().inflate(R.layout.header_view_spinner, null);
listView.addHeaderView(spinnerLayout);

And when we need to hide it, hide the layout’s content, not the layout:

    spinnerLayout.findViewById(R.id.spinner).setVisibility(View.GONE);

Now the header disappears from view. No more ugly space at the top!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Android Tidbits 6/8/2011: Warning! Warning!

Joe Moore
Thursday, June 9, 2011

Un-shadowed Method Warnings!

In response to yesterday’s question about Un-shadowed Method Warnings, Pivot Tyler points out that you can turn these on by calling Robolectric.logMissingInvokedShadowMethods(). Thanks!

Bad cached-robolectric-classes.jar

On two workstations every unit test was failing with the following error:

// …many levels of stack trace, finally:
Caused by: com.xtremelabs.robolectric.bytecode.IgnorableClassNotFoundException: msg because of javassist.NotFoundException: android.content.DialogInterface$OnShowListener
at com.xtremelabs.robolectric.bytecode.AndroidTranslator.onLoad(AndroidTranslator.java:80)
at javassist.Loader.findClass(Loader.java:340)

Cause: there was an old tmp/cached-robolectric-classes.jar that was causing these errors and our tests ran successfully after deleting it. That’s two answers from Pivot Tyler!

Don’t DDOS Yourself With Your Own App

The Bump Android team wrote an article about a good idea gone wrong. Moral of the story: not all devices behave the same, and this might cripple your servers rather than the devices.

Robolectric Google Group

Join it, contribute, and learn about unit testing your Android apps.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Pattern for Functional Testing

Pivotal Labs
Friday, November 14, 2008

Regular Selenium tests (in Java) might look like:

selenium.open("/login");
selenium.type("id=username", "bob");
selenium.type("id=password", "password");
selenium.click("Login");
selenium.waitForPageToLoad();
selenium.click("My Account");
selenium.waitForPageToLoad();
assertEquals("bob", selenium.getText("//table[2]/tr[3]/td[2]/");

After a few tests, this kind of thing becomes painful to manage. The typical solution is to create a bunch of constants for IDs and Xpaths, but that doesn’t help too much.

Fellow Pivot Mike Grafton came up with a cool pattern for improving on this. The idea is to create a class representing each page of your web app. Each class contains two types of methods: a bunch of action methods (clickMyAccountLink(), typeUsername()), and a bunch of inspection commands (isLoginButtonEnabled(), getLoggedInUsername()).

When an action takes you to a new page, the corresponding action method returns a new class representing that page. When it stays on the same page, the method just returns “this”. This allows methods to be chained to make the tests more readable.

Here’s how that test would look using this new pattern:

MyAccountPage myAccountPage = new LoginPage(selenium)
  .typeUsername("bob")
  .typePassword("password")
  .clickLoginButton()
  .clickMyAccountLink();

assertEquals("bob", myAccountPage.getLoggedInUsername());

The constructor of each page class should validate that it’s on the correct page (waiting if necessary, and perhaps asserting on the page title).

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

JAVA_HOME on Mac OS X

Alex Chaffee
Thursday, June 26, 2008

For the millionth time, cause I always forget…

Put this in ~/.bashrc:

export JAVA_HOME=/Library/Java/Home

[UPDATE: or this, which according to Mike Swingler, follows the Java version chosen in Java Preferences:

export JAVA_HOME=`/usr/libexec/java_home`

]

Also, run “sudo visudo” and add the line

Defaults        env_keep += "JAVA_HOME"

or else commands like “sudo gem install” won’t be able to find Java.

Without the above, I got the following error (which seemed to have been run through a baby-talk filter) when running “sudo gem install rjb”:

extconf.rb:44: JAVA_HOME is not setted. (RuntimeError)
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

XPath CSS Class Matching

Alex Chaffee
Tuesday, March 25, 2008

I’m writing Selenium tests again, which means a lot of XPath. Here’s a trick I learned thanks to this article on Push Button Paradise.

The problem is, how do you write XPath that matches one class in a multi-class element like

<div class='foo bar'>

? The standard XPath equality operator matches a full string, so

//div[@class='foo']

won’t work. The solution is arcane but I promise it works:

//div[contains(concat(' ',normalize-space(@class),' '),' foo ')]

Note that there must be spaces on either side of the class name ‘foo’.

Since this is quite a mouthful, I’ve extracted it into a helper method. Here it is in Java:

/**
 * Generates a partial xpath expression that matches an element whose 'class' attribute
 * contains the given CSS className. So to match &lt;div class='foo bar'&gt; you would
 * say "//div[" + containingClass("foo") + "]".
 *
 * @param className CSS class name
 * @return XPath fragment
 */
protected static String containingClass(String className) {
  return "contains(concat(' ',normalize-space(@class),' '),' " + className + " ')";
}
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Java Stink

Alex Chaffee
Monday, February 11, 2008

After about two years in which the only Java I wrote had a “Script” after it, I’ve recently started working in my old favorite language again. It was clear to me long before I made the leap that somewhere along the line Java took a sharp turn towards Scarytown. (Maybe the writing was on the wall when the “Hello World” program comprised five lines, two declarations, and a static reference, but back in 1995 we were all so excited about getting objects without C++ that our judgement was clouded.)

Anyway, I will always have a place in my heart for the old bird (picture a portly English matron with flower dress and pocketbook and floppy hat), but Stu at Relevance Blog points out why coding in Java now feels like trying to sprint with 30-pound weights strapped to my ankles.

Java is a high-ceremony language. At every turn, Java enforces a high busy-work/real-work ratio. Specifically:

  1. Java’s checked exceptions bloat code, make components harder to use and maintain, and lead to tons of boilerplate code, each line of which is a bug-in-waiting.
  2. Java’s new operator/constructors cannot pick a return type. The amount of code that exists only to work around this is staggering. Two entire cottage industries have sprung up to deal with this single issue: factory patterns and dependency injection.
  3. Java has no metaprogramming features to automate common tasks such as field accessors, standard constructors, and simple delegation.
  4. Primitives, functions, and classes are not first-class objects, leading to huge code bloat to deal with these types specially.
  5. Java’s core reflection and interception capabilities are clunky, requiring tons of bolt-on technologies to make them workable, including AOP, annotations, and code generators.

That’s a pretty big stink, but if you are used to it you probably can’t smell it anymore.

(And that’s not even mentioning the prevalent idioms of programming with massive amounts of indirection and wrappers and statics and service locators and and BigLongClassNamesThatIncludeTheirAncestry (I always say, “Do we call it a DogMammalVertebrateAnimal? No, we call it a dog!”) and redundant JavaDoc on every method and…)

I ranted and spoke and even blogged about some of these issues before, but now that I’m a visitor in that world I just feel vaguely amused and sad when I see all the hoops Java programmers still have to jump through. Yeah, control-space completion is nice, but gotapi works pretty well, and at the end of the day, no matter how many curly braces my IDE inserts for me, I’d rather have my code look like this:

parse_args(["--topping", "pepperoni"])

than this:

String[] args = {"--topping", "pepperoni"};
parseArgs(new ArrayList<String>(Arrays.asList(args)))


Wouldn’t you?

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (781)
  • rails (114)
  • testing (88)
  • ruby (84)
  • ruby on rails (70)
  • jobs (62)
  • javascript (56)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (24)
  • mobile (22)
  • process (21)
  • pivotal tracker (21)
  • cucumber (20)
  • design (19)
  • jasmine (19)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • tracker ecosystem (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • tdd (14)
  • gem (13)
  • css (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to java Feed
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >