Archive for the ‘Android Development’ Category

Dude, where’s my R?

What has that Horseman fellow been up to these days? He sure was quiet there for the past few months. What manner of mischief has he been plotting?

The Horseman has been plotting a number of different things over the past few months, brushing up skills and diving into various new and different environments. The topic of the day is about a mystery I encountered in one of the aforementioned environments. “Dude, where’s my R?”

I can hear you asking “Wait, what is an R?” Excellent question! An “R” is an Object that you’ll find in the Land of Coffee and Robots, which is more commonly known as Android development and perhaps less commonly known as Androtopia. The Horseman is more a squire than a Knight in these realms, so he’s had plenty of opportunity to royally botch his courtly etiquette. That’s quite easy to do too, as the language spoken in the Land of Coffee and Robots is Java, and it is definitely a language of strict rigor. Here is an example of where a total noob might find his or herself off the beaten track by asking the wrong citizen of Androtopia directions.

In the world of Android development, “R” is an object that contains a set of resources. These resources come, from among other places, a batch of .xml configuration files that you as the developer create and maintain. They store information about such things as screen layouts, and objects that are available to a particular screen of an application. Handy stuff! But what happens when you can’t find it and you know you wrote it?

The Androtopian atlas I’ve consulted is the Wrox Professional Android 2 Application Development book, so chosen due to the publication date and the relatively recent version of the OS covered. The tome instructs you in the mundane art of downloading Eclipse, and the arcane art of setting it up to develop Android applications. We’re going to skip ahead a bit to Chapter 5 by which time we’ve created many .xml files and should have a reasonably good feel for this whole R business.

Here’s the resource file I created, called “listitemlayout.xml”:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	>
<TextView
	android:id="@+id/itemTextView"
	android:layout_width = "fill_parent"
	android:layout_height = "wrap_content"
	android:padding = "10px"
	android:textSize = "16px"
	android:textColor = "#FFF"
	/>
 
</LinearLayout>

And here is a Java class written to represent an “Activity” in the application that uses this resource (among others).

package com.scriptocalypse;
 
import android.R;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.OnItemClickListener;
 
public class ContactPicker extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        //R.layout.
        setContentView(R.layout.main);
 
        Intent intent = getIntent();
        String dataPathString = intent.getData().toString();
 
        final Uri data = Uri.parse(dataPathString + "people/");
        final Cursor c = managedQuery(data, null, null, null, null);
 
        String[] from = new String[] {People.NAME};
        int[] to = new int[] {R.id.itemTextView};
 
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.listitemlayout, c, from, to);
 
        ListView lView = (ListView) findViewById(R.id.contactListView);
        lView.setAdapter(adapter);
 
        lView.setOnItemClickListener(new OnItemClickListener() {
        	@Override
        	public void onItemClick(AdapterView<?> parent, View view, int pos, long id){
        		c.moveToPosition(pos);
        		int rowId = c.getInt(c.getColumnIndexOrThrow("_id"));
        		Uri outUri = Uri.parse(data.toString() + rowId);
        		Intent outDataIntent = new Intent();
        		outDataIntent.setData(outUri);
        		setResult(Activity.RESULT_OK, outDataIntent);
        		finish();
        	}
        });
 
 
    }
}

There’s something desperately wrong with the above code. Can you pick it out? It might be tricky if you don’t know Java, or if you’re new to Androtopia. Even if you do know Java, this might trip you up as the code is all syntactically correct. Eclipse at least is helpful enough to point out that there are errors on all the lines in which we try to access R. So…

package com.scriptocalypse;
 
import android.R;  // <-- looks like we're importing android.R here...  Is that the problem?
import android.app.Activity;

So, imagine you’re walking down the road and you encounter what appears to be a fellow you’re looking for named “Roger”, and you ask him various questions about ids, contactListViews, and such. He simply doesn’t understand what you’re talking about. You begin to want to strangle him for his seemingly willful ignorance. Only much later do you realize that this is not the “Roger” you’re looking for. In fact, you don’t even need the import statement to access the “Roger” you’re looking for! After removing the import statement, the code compiles and works correctly.

“Well that was incredibly daffy of you Mr. Horseman, why did you import android.R if you didn’t need it?”

Ah, that’s the thing you see. I did not. There are many things I can say about the Eclipse IDE. In the interest of keeping the remaining entry expletive-free, I’ll simply say “Eclipse did it ‘automagically’ without my knowledge or consent, after somehow assuming that I wanted it.” Not knowing the lay of the land, and not being as familiar with the idioms of Androtopia and the strange customs of the Gremlins that live inside Eclipse, the import statements didn’t feel like an obvious place to look for a problem. It’s especially true since the statement to an untrained eye looks correct.

So let this be a lesson to intrepid explorers of new realms to be careful who one asks for directions, and to make doubly sure that there isn’t a Gremlin hiding in your code editor.

Tags: , , , , ,

No Comments