0

Android class “already added” when building

Posted by admin on Mar 22, 2012 in Uncategorized

I am working on an Android project constructed of:

  • The main app (very lightweight wrapper + AndroidManifest.xml)
  • The main library (where all the real work gets done)
  • Facebook-android-sdk
  • HockeySDK-Android

Recently, I started seeing the following error when building the app using ant:

[dx] UNEXPECTED TOP-LEVEL EXCEPTION:
[dx] java.lang.IllegalArgumentException: already added: Lcom/facebook/android/R$anim;
[dx] at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123)
[dx] at com.android.dx.dex.file.DexFile.add(DexFile.java:163)
[dx] at com.android.dx.command.dexer.Main.processClass(Main.java:486)
[dx] at com.android.dx.command.dexer.Main.processFileBytes(Main.java:455)
[dx] at com.android.dx.command.dexer.Main.access$400(Main.java:67)
[dx] at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:394)
[dx] at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245)
[dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:131)
[dx] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109)
[dx] at com.android.dx.command.dexer.Main.processOne(Main.java:418)
[dx] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:329)
[dx] at com.android.dx.command.dexer.Main.run(Main.java:206)
[dx] at com.android.dx.command.dexer.Main.main(Main.java:174)
[dx] at com.android.dx.command.Main.main(Main.java:95)
[dx] 1 error; aborting
Upon inspection, it appeared that there were multiple R.java files per module with different package names but the same content. Removing all the “gen” directories in the entire project resulted in a successful from the command line.

 
1

Building an Android app from the command line

Posted by admin on Aug 26, 2011 in Android

Why build an Android App from the command line?

For the purpose of creating a continuous integration build of an Android app, I needed to be able to build the app and its dependent modules from the command line.  This is done using ant.

Prerequisites

Of course, you must have the appropriate Android SDK installed for your development platform.  Make sure the tools directory of the Android SDK is in your PATH.

You’ll also want to install ant.

If you don’t already have Java installed, then maybe you should go visit the Android Developer site for some important background information.

Your Project

If you created your project using IntelliJ, then the build files mentioned below should be created for you automatically. If you created your project using Eclipse, then you’ll have to take an extra step to create the build files. Simply cd into the root directory of your project and execute the android command to generate the build files:

$ cd android-project-directory
$ android update project --path .

This creates build.xml, default.properties, and local.properties for your project.

Important Files

There are four build files of critical importance which you can find in the root directory of your project:

build.xml — this is the main ant build script.  Check this file into your version control system.

default.properties — has a huge warning that says it’s generated by the Android tools and should not be modified. Check this file into your version control system.

ant.properties (optional) — allows you to add application-build-specific entries used by the build script. Typically empty for a straightforward Android app build but can be customized for non-standard directory structure or build dependencies.  Check this file into your version control system or omit it entirely from the project if you have no customizations or build dependencies.

local.properties — also generated by Android tools but should not be checked into your version control system. This is where the local path to your Android SDK directory root is specified, and this typically varies from one machine or build environment to the next.

Build Command

In order to build the app from the command line, cd to the root directory of your Android project (where the above files live and typically also where your src directory and your AndroidManifest.xml file live) and execute the ant command:

$ cd android-project-directory
$ ant clean debug

This command removes any leftover binaries or other artifacts from a previous build and rebuilds the app from scratch. If that is successful, then it packages and signs a debug version of the app. The console output from the command tells you where you can find the resulting .apk file for the app.  Here’s an example of the console output from a successful build showing the location of the resulting .apk file:

$ ant clean debug
Buildfile: /Users/mharper/Development/Android/Demo/HelloCI/build.xml
[setup] Android SDK Tools Revision 10
[setup] Project Target: Android 2.2
[setup] API level: 8
[setup]
[setup] ------------------
[setup] Resolving library dependencies:
[setup] No library dependencies.
[setup]
[setup] ------------------
[setup]
[setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
[setup]
[setup] Importing rules file: tools/ant/main_rules.xml
clean:
[delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/bin
[delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/gen
...
compile:
[javac] Compiling 2 source files to /Users/mharper/Development/Android/Demo/HelloCI/bin/classes
...
debug:
[echo] Running zip align on final apk...
[echo] Debug Package: /Users/mharper/Development/Android/Demo/HelloCI/bin/HelloCI-debug.apk
BUILD SUCCESSFUL
Total time: 4 seconds

Building an App with Dependencies

It is common for an app to depend on one or more libraries that are built with a separate project. Thankfully, the Android build files make this easy to deal with.

Let’s say my HelloCI app depends on a HelloCILib that is a separate project built as an Android library.  Let’s also say that the HelloCI and HelloCILib root directories are in the same directory:

$ ls
HelloCI		HelloCILib

In order for the HelloCILib to be built before HelloCI, all you have to do is to reference its root directory path in the build.properties file of the main project (HelloCI, in this case) thusly:

android.library.reference.1=../HelloCILib

You can add more dependent projects simply by bumping the number at the end of the property, e. g. android.library.reference.2 etc. I understand that you should not leave any gaps in the numbering, however.

Notice how the build looks slightly different now that the dependent library is included:

$ ant clean debug
Buildfile: /Users/mharper/Development/Android/Demo/HelloCI/build.xml
    [setup] Android SDK Tools Revision 10
    [setup] Project Target: Android 2.2
    [setup] API level: 8
    [setup]
    [setup] ------------------
    [setup] Resolving library dependencies:
    [setup] /Users/mharper/Development/Android/Demo/HelloCI: ../HelloCILib => /Users/mharper/Development/Android/Demo/HelloCILib
    [setup] ------------------
    [setup] Ordered libraries:
    [setup] /Users/mharper/Development/Android/Demo/HelloCILib
    [setup] ------------------
    [setup]
    [setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
    [setup]
    [setup] Importing rules file: tools/ant/main_rules.xml
clean:
   [delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/bin
   [delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/gen
...
compile:
    [javac] Compiling 4 source files to /Users/mharper/Development/Android/Demo/HelloCI/bin/classes
...
debug:
     [echo] Running zip align on final apk...
     [echo] Debug Package: /Users/mharper/Development/Android/Demo/HelloCI/bin/com.standalonecode.HelloCI-debug.apk
BUILD SUCCESSFUL
Total time: 4 seconds

Summary

Building an Android app from the command line is very straightforward, especially if you have a standard Android app directory structure. All of this work is leading up to creating a continuous integration build under Jenkins at cloudbees.com which is the subject of another blog post.

The source for this example can be found on GitHub.

 
0

It’s the mistakes that crack me up

Posted by admin on Jul 12, 2011 in Uncategorized

When I was working on ResEdit for Apple back in the mid-90s, I made a mathematical mistake that caused resizing to be geometric instead of linear. Man, you could resize a control very quickly that way! Anyway, today’s mathematical mistake wasn’t quite as serious, but still brought me a good chuckle.

Maybe I should make the circle fit *inside* the rectangle

 
0

Android Emulator Seeks Network Connection

Posted by admin on Apr 13, 2011 in Android

I wasted a good amount of time this morning due to the Android Emulator’s inability to be moved from one network to another.

Because it takes so damn long to startup, I typically keep the Android Emulator running when I am working on Circle 8 for Android (as I have been lately). In a typical day, I encounter at least three wifi networks: home, office, and the coffee shop.

Apparently, the Emulator prefers a monogamous relationship with networks and thus doesn’t switch over to a new wifi connection. I was trying to setup the Email app in the Emulator to connect to my email account and it failed over and over again. I finally decided to restart the Emulator, thinking that maybe it was lost with respect to the network. Sure enough, restarting the Emulator resulted in being able to browse to a web page as well as setup the Email app no problem.

Edit (August 2011):

I have since abandoned the Emulator in favor of developing directly to an Android device. Significantly snappier and less prone to bizarre errors.

 
0

Wait for it…

Posted by admin on Jan 19, 2011 in Ajax, Cucumber, Rails, Testing

On my current Rails project, I have been working on constraining “check-ins” to once daily or once weekly. From a Cucumber scenario perspective, this means using Timecop to travel to a specific time/date, popping a jQuery dialog, entering some data, and pressing the Submit button. This procedure is then immediately repeated, traveling to a different point in time. Upon completion of the successful path, I was asserting that both “check-ins” took place by looking at the model/database. Unfortunately, this would fail quite randomly. It was as if the second time travel was taking place before the first check-in was being written to the database. If so, this would cause the second check-in to fail the daily or weekly constraint during validation.

What I needed to do was WAIT — wait for the check-in dialog to close before the second time travel.

It took some poking around, but I finally settled on the following step definition:

When /^I wait for (.*)to finish$/ do |sugar|
  page.wait_until do
    done = page.evaluate_script("window.jQuery.active == 0")
    putc done ? '*' : '+'
    done
  end
end

This allows me to write a step such as:

And I wait for the check-in to finish

This step prints a + every time through the loop while the page is still active, and then a * when it’s done. (Obviously, this is window dressing and not integral to the success of the step.) Not only did this fix the scenario failures I had due to the race condition, it also got rid of the random “connection reset” errors I was seeing.

 
0

Posted by admin on Sep 2, 2010 in iPod / iPhone

In an iPhone app I’m working on which uses an MKOverlayView subclass, I found that the lines I was drawing were thinner on iPhone 4 than on iPhone. Simple math to the rescue so the line has the same thickness on both platforms (e. g. I want a uniform lineWidth of 3.0):

overlayView.lineWidth = 3.0 * [[UIScreen mainScreen] scale];

 
0

Rails 3: Validation error display using HAML

Posted by admin on Jul 15, 2010 in Rails, Uncategorized

Here’s what I am using at the top of the view I just converted to HAML in a Rails 3 app to display any validation errors. Adjust for your own model and preferences as desired.

%h2 New Form in HAML
= form_for(@new_model) do |f|
  - if @new_model.errors.any?
    %div#errorExplanation
      %h2= "#{pluralize(@new_model.errors.count, "error")} prohibited this new_model from being saved:"
      %ul
        - @new_model.errors.full_messages.each do |msg|
          %li= msg

Edit 16-July-2010: It turns out that Rails 3 has a template engine that you can use to generate the views for you using HAML when you scaffold up a resource. Watch Ryan Bates’ excellent Railscast Episode 216 for more information.

 
0

Rails (3?): Skip Test

Posted by admin on Jun 14, 2010 in Rails, Ruby, Testing

In updating an existing Rails app to run under Rails 3 (beta 4), I realized you could indicate that a certain test case should be skipped.  Literally, just add “skip” inside of the test (I added it to the top of one of mine as it was actually a work in progress) followed by an optional message.  For example:

test "should take the warp core offline" do
  skip
  warp_core.dismount
end

Very useful.

 
0

I just saw something thought-provoking

Posted by admin on May 18, 2010 in Business

My office is in what I refer to as “the penthouse suite” in a medium-aged building in the core old business area of Sunriver, OR.  As such, I overlook one of the main two-lane roads that traverses the length of Sunriver north-south, the main part of the mall, a morsel of Mt Bachelor, and a TON of trees.

Just a moment ago, a bird lit on the extreme tippy-top of a fir tree whose peak is only a few feet higher than my office, making the tree about 9 meters tall.  He landed on a treetop that is only about 1 square cm.  I immediately thought to myself, “I wonder why he landed on that spot? It’s difficult to land on and difficult to hold onto.  His bird feet can just barely hang on because there’s so little to hold onto.  He easily could’ve landed and rested in some comfort on a lower branch.”  To which I immediately responded to myself, “It obviously isn’t how comfortable he is that matters; it’s what he can see and do from there.”

My bird friend surveyed the area from there for about 60 seconds, and then he flew off — doubtless to somewhere he’d just seen from his recent perch.

I have an idea for a new logo for Standalone Code.

 
0

Those pesky Xcode windows

Posted by admin on May 15, 2010 in Mac OS X, Xcode

When working on an Xcode project, it’s really easy to end up with a dozen windows open.  You did know that you can close all of them and leave just the main project window open, right?

Just option-click in the close “box” (that’s what we used to call it when it was square, is it the “close circle” now?) of any editor window, just not the main project window.  Et voilà — all windows closed.

Copyright © 2014 Standalone Code LLC All rights reserved. Theme by Laptop Geek.