Roger's Blog | Well, I think it's interesting.

CAT | Android

Since my Eclipse installation blew up I’ve been using the IntelliJ IDEA Community Edition for Android programming. Like many others I prefer working with a dark editor background instead of a blinding bright white background but I found there are very few places you can find pre-made IntelliJ color schemes and there’s no place like http://studiostyl.es for IntelliJ. So I translated a couple of my preferred Visual Studio color schemes (Son of Obsidian and Ragnarok Blue) to IntelliJ.

You can download either or both color schemes from my Dropbox. Both SonOfObsidian.zip and RagnarokBlue.zip contain an XML file of the same name; put the XML file in your home\.IntelliJIdea10\config\colors directory (you will need to restart IntelliJ before it will pick up the files.) After you restart IntelliJ, go to File->Settings->Editor->Color & Fonts and select the scheme you want to use from the Scheme name dropdown. Both schemes use the Consolas font.

Translating the schemes was pretty straightforward with only a couple of gotchas. First is you have many more customization options in IntelliJ than you have in Visual Studio. In IntelliJ you can have different colors for instance fields vs. static fields vs. parameters, line comments vs. block comments (plus others). The second gotcha is that the settings for Red and Blue seem to be reversed. For example, in the Ragnarok Blue scheme the plain text background setting is 0x00261A10. I used a web site to quickly translate the hex code to it’s RGB equivalence; there are many sites that can handle the conversion. Drop ‘0x’ and the first ‘00’ and plug in ‘261A10’; the code comes back as Red:38, Green:26, Blue:16. But if you plug that into IntelliJ’s RGB color tab, it won’t be right. You have to enter it backwards as Red:16, Green:26, Blue:38. I tried a couple of different translation sites with the same results so the problem is either in Visual Studio or IntelliJ.

Mappings from the .vssettings file to IntelliJ are pretty simple (anyplace in .vssettings where the color is 0×02000000 it means the color was left at the default:)

  • Comment:  Java->Line comment & Java->Block comment
  • Plain Text:  General->Default text
  • Selected Text:  split between General->Selection background and General-Selection foreground
  • Brace Matching (Rectangle): General->Matched brace (background)
  • Identifier:  Used this in a few places. Java->Instance field, Java->Local variable,Java->Method call, Java->Static field
  • Number: Java->Number
  • Operator: Java->Operator sign
  • String: Java->String
  • User types: Java->Class
  • User Types(Interfaces):  Java->Interface
  • Line Numbers:  General->Line number
  • Keyword:  Java->Keyword
  • XML Attribute:  XML->Attribute name
  • XML Attribute Value:  XML->Attribute value
  • XML Comment:  XML->Comment
  • XML Name:  XML->Tag name

·

This afternoon I posted the first preview of the 2011 CodeStock Android app on the project page at http://code.google.com/p/codestock2010 (in hindsight I probably shouldn’t have included “2010” in the project name.) So far this year’s edition has a few features:

The home page displays a special background with a countdown timer until the opening of the conference.

device

It can also display a running stream of postings from Twitter than either mention CodeStock or originate from the official @CodeStock Twitter account. From Menu->Options, select Enable Twitter. You’ll be asked to authenticate to Twitter and grant Aremaitch Dev Test permission to access your Twitter account (this name will change when the app is finally released to the Market.) Once this is done you’ll be able to set how often your device will download tweets, how long each tweet is displayed, and how many days of tweets to keep.

preferences

There have been many internal code changes to help minimize memory and cpu usage; feel free to take a look. And, of course, if you see something that could have been done better, don’t hesitate to let me know.

I’m planning to deepen the Twitter integration by letting you send tweets tagged with #CodeStock. I’m also planning to add session notifications and integration with the device calendar. Let me know if you have any ideas for additional things to add.

No tags

I’m a bit late in posting this but on November 6th when I spoke on Android and .NET Services at the Fairfield / Westchester County Code Camp I sat down for an interview with Peter Laudati’s Connected Show podcast. The episode is live and available for your listening pleasure here.

No tags

 

Had a great time this past weekend in Richmond, VA for Richmond CodeCamp X. Had a good turnout at a great venue and while my session was rather sparsely attended we had some good discussions and questions.

As promised here is the slide deck and the sample apps. The ZIP file does not include the Restlet and ksoap2-android libraries (because my web host limits upload sizes) but you can download Restlet from http://www.restlet.org. There has been a revision to the Restlet library (from v 2.0.0 to 2.0.1) but I’ve tested the sample application to make sure it works with 2.0.1. There have also been changes to the ksoap2-android library in that the dormant 2.4 fork has been taken over by Manfred Moser, who had created the original 2.5 fork. The 2.5 fork (which is the one my demo used) is gone and only the 2.4 fork is available. The 2.4 fork can be downloaded here. The Eclipse folder is meant to be the root of an Eclipse workspace so I didn’t include the .metadata folder.

Inside the folders for the two Eclipse projects there are “libs” folders that are placeholders for the Restlet and the ksoap2-android libraries; you will probably have to fix-up the classpath for both projects. The Visual Studio project is meant for Visual Studio 2010 Professional or higher.

Android and .NET Services Presentation

No tags

With CodeStock behind us I thought it would be a good idea to do a little post-mortem analysis of the CodeStock Android app to see what went right and what went wrong.

What Went Right

  • Scanning a QR code to link My Sessions with the web site’s Schedule Builder. I didn’t know ahead of time that the web site would generate a QR barcode to access the user’s schedule. I had started designing a layout to prompt the user to enter their website id but scanning the barcode is much more in keeping with the Android mantra of a seamless device experience. There were a few people that mentioned before and after the conference that they didn’t know you could do that with Android (having one application call another, unrelated app that returned data to your app.) Definitely cool.
  • Downloading speaker photos and caching them to the SD card. Downloading the photos on a background AsyncTask. and saving them to a directory on the SD card avoided having to download them multiple times. The trickiest part was figuring out how to avoid having the photos show in the device’s Gallery app. The solution was to add a file named “.nomedia” to the directory where the photos are stored. The file could be zero-length; it just needed to exist. It was also a surprise how flexible the TextView widget is. It can hold much more than just text by using Spannables and Editables. It’s something I want to spend more time understanding.
  • Parsing speaker bio’s and session synopsis. Many of the speakers originally uploaded their bio’s and their session’s synopsis with embedded Html formatting. A couple of speakers apparently used Save as Html from Microsoft Word and just pasted the document into the web site, complete with all the Microsoft object model junk. When I started the project I fully expected to have to write all sorts of nasty code to parse out this junk. Turns out the TextView widget combined with the android.text.Html and the android.text.util.Linkify classes is fairly forgiving of what you feed it. The Html.fromHtml() method will take nasty html and return something sensible for TextView to display while Linkify.addLinks() will scan the contents of the TextView and turn recognized text into hyperlinks. It was fairly simple to add a filter that extended Linkify.addLinks() to recognize Twitter handles and to add a handler to Html.fromHtml() to teach it to handle html tags it didn’t natively support. For a complete picture, see the code in DisplaySessionDetailsActivity.java, especially the displaySessionInfo() method and the MyTagHandler nested class.

What Went Wrong

  • Image icons on the start screen suck. No other way to state it. I’m not an artist and can’t draw to save my life (I’m so jealous of people that can create nice artistic images.) That’s one of the reasons I haven’t done much with ASP web pages because I can’t come up with a layout that doesn’t look like it was done by a developer.
  • Database access is fragile. The coordination of opening and closing the database was tricky to get right without the OS throwing a “Database leaked” exception and any changes to the app that involved db access would break the access. As I mentioned in my presentation you don’t have to use the “extending SQLiteOpenHelper” pattern. I’m going to try to refactor it to use some sort of singleton pattern, perhaps opening the database at app startup and closing it only when the app completely exits.
  • Handling orientation changes while AsyncTasks are running is fragile. Because Android basically kills then restarts your activity when the device orientation changes creating and showing a ProgressDialog in AsyncTask.onPreExecute() then dismissing it in AsyncTask.onPostExecute() can cause a Window Leaked exception. What happens is the recreated Activity knows nothing about the AsyncTask and the AsyncTask has an invalid reference to a non-existent activity. I changed My Sessions to download the Schedule Builder data using an AsyncTask but had the activity (MySessionsActivity.java) own the ProgressDialog instead of the GetScheduleBuilderSessions AsyncTask class. The class still sets the text in the ProgressDialog and shows and dismisses it but the dialog is owned by the activity. It seems to work fine and is much simpler than the mess in StartActivity.java.

What’s Next

The CodeStock data API will be staying up for at least a while so I plan to correct and refactor some of the above issues. I’m also planning to target Android 2.1 and higher so I can do some of the things I wanted to do but couldn’t because I didn’t want to leave the 1.5 and 1.6 users behind. I also have another idea that I’ll keep to myself for the moment. I’m also planning to port the application to Windows Phone 7. I do plan to blog about most of this.

Forty-nine people downloaded the app (28 of you still have it installed) and for the most part the comments were very nice. Several people come up to me during the conference to say they liked the app and used it all the time. Thank you for the kind words. If Michael wants me to I will definitely do another one for next year.

No tags

Just a quick post that the next part is going to be delayed. The baseball OData feed is down and I have no idea when it will be back (I don’t have any control over it.) So I’ll have to regroup and figure out what to do in case it doesn’t come back.

No tags

I’ve been particularly fond of using Visual Studio with a dark color scheme and the Consolas font and I wanted to use the same settings in Eclipse. It took a bit of Googling and hunting as the settings for fonts and colors are a bit more scattered in Eclipse than they are in Visual Studio.

To change the default editor font in Eclipse, select “Preferences” from the “Window” menu. From the tree on the left side of the Preferences dialog, select General->Appearance->Colors and Fonts. In the right pane tree select Basic->Text Font then click “Edit…” Select your desired font (I use Consolas 9pt.) After you’ve selected the font, several other font settings in the Preferences dialog will default to using the text font. If you expand the Java node you will see that “Java Editor Text Font” and “Properties File Editor Text Font” have both changed to match the basic text tont while “Javadoc display font” has not. You can override each font setting and have each one use a different font if you really want. Several bloggers have mentioned their preference for using the Dina font for the Console window in Visual Studio 2010; you can use it in Eclipse too for the device & emulator log (called ‘”LogCat.”) You can download the Dina font from the author’s website. To change the device & emulator log font, select Android->LogCat in the Preferences dialog, click Change and select the Dina font you downloaded.

Most of the color preferences for Java coding are under Java->Editor->Syntax Coloring and General->Editors->Text Editors but the rest are spread throughout the Preferences dialog. The easiest way I found to work with them is to start editing something (Java code, or an XML file,) then right-click the editor and select “Preferences” from the context menu. What will appear is a Preferences dialog that has been filtered to only show the entries that are relevant to the current editor. For a quick start using pre-made color themes, see this post and this post.

One other set of changes you may want to make is to change brace handling to be more like C#. The convention in Java is to place opening braces on the same line as the structure they open:

public static MainClass {
  public static void main(String[] args) {
    ...
  }
}

rather than the C# style:

public static MainClass
{
  public static void main(string[] args)
  {
    ...
  }
}

That said, I’m a believer in using the conventions of the language rather than trying to force one language to act like another.

These settings are located in the Preferences dialog under Java->Code Style->Formatter. Within this settings page you can create multiple sets of formatting options (each with their own settings) and even have different formatting sets for different projects. In fact, the level and degree of code formatting options for Java far surpasses Visual Studio for C#.

I encourage you to review the other Java preference settings. There are code style analysis settings under Java->Compiler and several CodeRush-like settings under Java->Editor. The ? icon in the lower left corner of the Preferences dialog will open context-sensitive help about the current panel (most dialogs in Eclipse have this.)

You can download my tweaks and color settings in the zip file at the bottom of this post. It includes a readme file that details how to install it into Eclipse. It’s not completely necessary but without it your work with Eclipse won’t look like the screenshots. Up to you. Now let’s move on to some code.

When we last left the coding we had a Java project called JRERestletServiceRefGenerator with a package called com.droidbaseball.svcgenerator and a class with just template code called MainClass.java:

image

At the top is the package declaration. Again, think of this like a .NET namespace. In fact if you hover the mouse over the main method the full name of the method is com.droidbaseball.svcgenerator.MainClass.main.

The main method is decorated with a Javadoc block (signaled by the /** comment) and includes the @param Javadoc tag. This is similar to the XML comment construct in C# signaled by the /// comment. For details about Javadoc see here. This automatic decoration of the generated code can be controlled in the Preferences dialog under Java->Code Style->Code Templates->Comments. The “TODO” comment in the method body is a task tag and performs a similar function as the task list in Visual Studio. You can control the generation of these generated comments in Preferences->Java->Code Style->Code Templates->Code and you can add additional task tags under Preferences->Java->Compiler->Task Tags.

The little marks to the left and right of the TODO line are annotations. The left margin is the vertical ruler and the right margin is the overview ruler. When there is an error, for example, that prevents the code from compiling it will show up in the overview ruler as a red mark; hovering over it will show a summary of the error and clicking it will jump to that line in the source file. There are several annotations; they can be controlled in Preferences->General->Editors->Text Editors->Annotations.

We’re going to add some code to the main method to call the OData service generator. Since this is pretty much a throw-away app we’ll hard code it. Remove the TODO line from the main method and add one line to the main method:

Generator.main(new String[] {
  "http://173.46.159.199/baseballstats/BaseballStats.svc",
  "C:\\projects\\BaseballService"
});

Save the file. It will look like this:

image

There are a couple of things to notice about this code. First, the Generator.main static method accepts one parameter: an array of String (arrays in Java are zero based just as in C#.) The syntax for creating an array “on-the-fly” is identical to C#. The first array element is the URL of the service and the second array element is the destination directory for the generated code (this example assumes you have the path “C:\projects\BaseballService” created. If you don’t, change this parameter as desired.) Notice the double backslashes. In Java the backslash is the escape character same as it is in C#. But there’s one important difference. In C# you could write this line like this:

Generator.main(new string[] {
  "http://173.46.159.199/baseballstats/BaseballStats.svc",
  @"C:\projects\BaseballService"
  });

The @ sign in front of the destination directory indicates a verbatim string in C#. Java has no equivalent syntax; you need to use the double-backslash syntax.

Second, notice there’s a red underline beneath Generator, and red annotations in the vertical ruler, overview ruler, and the title tab. These are all error indicators. Hovering over either ruler annotation will display the error but hovering over the red underline will show a “quick fix” window. This is a context-sensitive list of suggestions by Eclipse to fix the error (you can also display this window by putting the caret in the underlined section and pressing Control + 1.) The quick fix window for this problem is this:

image

Usually the first one in the list is the most appropriate. In this case it is complaining that it cannot resolve the reference to “Generator” and is suggesting to import the Generator class from the org.restlet.ext.odata package. If this sounds familiar, it should. It’s the same as Visual Studio complaining that the “type or namespace name could not be found” and suggesting adding a using directive. Pick the first item in the list: Import ‘Generator’ (org.restlet.ext.odata) but don’t save the file yet. It will add the line “import org.restlet.ext.odata.Generator” to the top of the source file. Notice that the error indicator in the overview ruler has disappeared, but the error indicator in the vertical ruler has simply grayed out while the error indicators in the editor’s tab and in the package explorer are still displayed in red. This shows a subtle difference between background compiling in Eclipse and Visual Studio. If you perform the equivalent steps in Visual Studio, the error annotation will go away as soon as you add the using line. This shows that background compilation occurs as soon as you stop typing for more than a moment or two. Now in Eclipse save the file. Notice now that all the error indicators disappear. This shows that, in Eclipse, the compilation will not occur until you save the file. If there is a setting in Eclipse to make it work like Visual Studio I haven’t found it yet. But I actually prefer the Eclipse way.

Now that we’ve added the import and fixed our error we can run it. By default Run is Control + F11 and Debug is F11; if you want to remap that (and the debug Step, Step-Over, and Step-Into keys) to match Visual Studio you can do that in Preferences->General->Keys. Press F11 to run it in Debug mode.

Crap! We crashed. Why? Well, here’s what we got in the console window:

Exception in thread “main” java.lang.NoClassDefFoundError: freemarker/template/Configuration

at org.restlet.ext.odata.Generator.generate(Generator.java:236)

at org.restlet.ext.odata.Generator.main(Generator.java:134)

at com.droidbaseball.svcgenerator.MainClass.main(MainClass.java:14)

Caused by: java.lang.ClassNotFoundException: freemarker.template.Configuration

at java.net.URLClassLoader$1.run(Unknown Source)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(Unknown Source)

at java.lang.ClassLoader.loadClass(Unknown Source)

at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)

at java.lang.ClassLoader.loadClass(Unknown Source)

… 3 more

There’s a “ClassNotFoundException” in there. Basically that’s Java runtime saying “there’s a reference to a class in here that the compiler didn’t know about and I don’t know where it is.” There is a reference within the Generator.main() method to the “freemarker.template.Configuration” class. If you look in the Restlet lib directory (C:\lib\restlet-jse-2.0rc3\lib) there is a readme file that details the dependencies. According to the readme when using the OData extension we need a reference to org.freemarker_2.3. To add it, right-click the project in the Package Explorer, select Build Path->Configure Build Path. Select the Libraries tab and add the external Jar C:\lib\restlet-jse-2.0rc3\lib\org.freemarker_2.3\org.freemarker.jar. After clicking OK re-run the app using F11 and it will run to completion.

So what did we end up with? If you look in C:\projects\BaseballService you’ll see BaseballStatsOdataOrcswebService.java and a directory named baseballstatsmodel that contains 18 .java files. BaseballStatsOdataOrcswebService.java is essentially the service proxy; this is equivalent to what Visual Studio’s “Add service reference” feature would generate. The 18 files in the baseballstatsmodel directory are the entity objects.

Next time we’ll setup the Android project and review its parts. Then we’ll setup the layout of the first screen.

DefaultEclipsePreferences

· ·

In part 1 I introduced the pieces needed to start developing for Android. For the remaining parts I’m going to make a few assumptions:

  • You installed the 32bit version of the JDK to the default location.
  • Eclipse is installed in C:\eclipse. There is no installer, just unzip the distribution archive into the rot of the C: drive.
  • The Android SDK was installed in C:\android-sdk-windows.
  • You followed the directions here to install the ADT Plugin, set the Android preferences to point to the SDK install location, and added the Android platforms to the SDK.
  • You downloaded the Restlet Java extension for OData and unzipped the Android version into C:\lib\restlet-android-2.0rc3 and unzipped the JSE version to C:\lib\restlet-jse-2.0rc3. I found it easier while learning Java and OData to use the JSE version rather than the Android version. Release Candidate 3 is the current release recommended for new development (and version 2.0 is the one with OData support.)
  • The first time you started Eclipse you accepted the default location for the workspace. You can have multiple workspaces even though the default for Eclipse is to put everything in the same workspace.

(Note: I actually completed this post a few days ago but as I was getting ready to post it Restlet posted Release Candidate 3 so of course I had to stop and test the sample with the new version. We now resume our regularly scheduled post.)

I’ll start with a few user requirements for the baseball application:

  • The user should be able to enter a player’s last name. She should also be able to specify that she wants to search only for active players or for all players that ever played Major League Baseball.
  • The user should then be able to select the player she is interested in from a list of all the players whose last name matched. The list should show enough information about the matching players to let her determine the correct one (you would be surprised how many players with the same name have played decades or even a century apart. Yes, the data goes that far back.)
  • After the user selects the player we should show her more details about the player: where he played, where he went to college, where he was born, his  batting statics, fielding statistics, and pitching statistics.

And some technical requirements:

  • The statistics generally will not fit on a standard Android screen in portrait mode. This means we will need to react to and intelligently handle a device orientation change. We may even want to force landscape mode and not permit changing to portrait mode.
  • We will be querying a live server over the network (either wireless or WiFi.) Obviously network queries can be time-consuming and Android has similar issues as .NET with respect to long running, blocking tasks running on the UI thread. Android also has similar restrictions as .NET with respect to updating the UI from a background thread.
  • We would like to use good, solid software engineering principles. Separation of concerns, good testability, DRT, etc.

So without any further delay here are some prototype screen shots:

startscreen playersearchlistscreen playerdetailsscreen

playerbattingstats playerfieldingstats playerpitchingstats

First row left to right: start up screen, search results list, player details.
Second row left to right: batting stats, fielding stats, pitching stats (if none found.)

OK, so it’s obvious where I fall on the whole designer vs. developer spectrum.

To get started our first job will be to create a project to generate the OData references and code for the baseball stats service. The Restlet library can query the service’s metadata and generate the entity classes automatically but that functionality isn’t in the Android libraries; it’s only in the JRE libraries. So within Eclipse click the File menu and select New->Java Project (not Android Project.) In the “New Java Project” dialog enter “JRERestletServiceRefGenerator” as the Project name and leave all the other settings at their default. The dialog should look like this:

New Java Project

Click “Next". On the second page (Java Settings) we’re going to add the additional libraries we need (this is comparable to Visual Studio’s “Add Reference” dialog except in Eclipse you can specify the external libraries at the same time you create the project.) Select the “Libraries” tab, click “Add External JARS…” and navigate to C:\lib\restlet-jse-2.0rc3\lib. Select “org.restlet.jar” and “org.restlet.ext.odata.jar” and click Open. It should look like this:

image

Click the triangle next to “org.restlet.ext.odata.jar” to expand the node. Select “Source attachment: (None)” and click the Edit button. In the Source Attachment Configuration dialog click the External Folder button, select “C:\lib\restlet-jse-2.0rc3\src” and click OK twice. Then select “Javadoc location: (None)”, click the Edit button, select “Javadoc URL” (which should be selected by default,) click the Browse button, select “C:\lib\restlet-jse-2.0rc3\docs\ext” and click OK twice. These settings tell Eclipse where to find the source code and the Javadoc for the Jar file (Javadoc is roughly equivalent to Intellisense.) We’re going to repeat the process for “org.restlet.jar” except the Javadoc location is “C:\lib\restlet-jse-2.0rc3\docs\api”. When done, the library settings tab should look like this:

image

Click “Finish.” Eclipse will chug for a second or two and then drop you into the Package Explorer with the newly created project.

If you expand JRE System Library you will see some of the Jar files that make up the Java runtime. If you expand Referenced Libraries you’ll see the two Restlet libraries we added plus a few more that were automatically added due to references:

image

“src” is where our source will go. Right click src and select New->Package. Think of a Package like a .NET namespace. We’ll use “com.droidbaseball.svcgenerator” as the package name.

In straight Java the package name can be just about anything you want but for Android the package name must follow a specific pattern. This is because on Android every application must have a different name so the OS can tell them apart and the package is part of the unique name. Click Finish to create the new package.

The final step for this post is to create our first source file. Right click the package we just created and select New->Class. This brings up the New Class Wizard:

image

Most of the fields are already filled in for us; we only have to add a couple of things:

  • Give the class a Name; we’ll use “MainClass”
  • Since this is our main class, we need an entry point; check the box next to “public static void main(String[] args)” – this should look familiar to C# developers.

Like .NET, everything in Java is an object that ultimately derives from java.lang.Object. One other point before we leave this dialog: many dialogs in Eclipse have content assist in various fields. Click in the Superclass field and notice a tiny light bulb show up to the left of the field:

image

That’s an indicator that content assist is available. Blank out the field, then type Obj and press Control+Space:

image

Every class that Eclipse currently knows about and that matches what you started entering in the field will be displayed in a popup list that you can choose from. This will come in handy later when we start creating Android classes.

For now, be sure the superclass is “java.lang.Object” and click Finish. Eclipse will think for a second then open our new class file.

Next time we’ll look at customizing Eclipse to make it a little more like Visual Studio. We’ll also add the code to our generator class (there isn’t much) and generate out service classes. Then we’ll set up the Android project.

No tags

Theme Design by devolux.nh2.me