Tuesday, May 24, 2011

Eclipse - Widget disposed too early

I'm using Ubuntu 10 (64-bit) and just installed Eclipse for C/C++. The first time I tried to start the application, it threw this error (plus a whole stack dump):
Widget disposed too early
This blog is the first resource that actually worked.

Wednesday, May 18, 2011

Android: updateAppWidget couldn't find any view, using error view

This was a vexing error that, according to all documentation and The Google, should not have been thrown. After a day of change code around, I stumbled on this post. The moral of the story is that you cannot change a button image; you can only change something defined in your layout XML as a <ImageView>

Wednesday, May 11, 2011

JSON-RPC from Android

There is a dearth of utilities on the Internetz that describe how to make a JSON-RPC 2.0 call from an Android device to a server somewhere. Attempts to create handy classes and posts on StackOverflow never quite seemed to do the trick. So... here it is. No fanfare.

Suppose you want to send this JSON string using HTTP using Content-type: application/json
{"jsonrpc":"2.0","method":"myMethod","params":[{"first":"A","second":"B"}],"id":"0"}

What makes this different from a regular HTTP call is the presence of an attachment and the Content-type: application/json designation. Here is the POST method:

 public HttpResponse doPost() throws JSONException, ClientProtocolException, IOException {
  HttpClient client = new DefaultHttpClient();
  
  JSONObject json = createMethodCall("myMethod", createMethodParams());
  Log.d(LOGTAG, json.toString());
    
  HttpResponse response = client.execute(createRequest(json));
  return response;
 }

I use the org.json libaries to construct my JSON object because the toString() method produces syntactically-correct JSON with no effort on my part:

 public JSONObject createMethodCall(String method, JSONArray params) throws JSONException {
  JSONObject json = new JSONObject();
  
  json.put("jsonrpc", "2.0");
  json.put("id", "0");   // we don't really use this so value is always zero
  json.put("method", method);
  json.put("params", params);

  return json;
 }
 
 public JSONArray createMethodParams() throws JSONException {
  JSONArray params = new JSONArray();
  
  // Default params that appear in all method calls
  params.put(new JSONObject().put("first", "A"));
  params.put(new JSONObject().put("second", "B"));
  
  // To add custom parameters, add to the return value rather than here, or this method becomes messy
  return params;
 }

The final trick is that HttpEntity is the Java object for MIME attachments. Therefore, attaching the JSON string as a StringEntity and declaring the content type as "application/json" is required for the server to recognize it as a valid JSON-RPC call.

 public HttpPost createRequest (JSONObject json) throws UnsupportedEncodingException {
  HttpPost request = new HttpPost(this.server + this.url);

  StringEntity entity = new StringEntity(json.toString());
  request.setEntity(entity);
  request.setHeader("Accept", "application/json");
  request.setHeader("Content-type", "application/json");
  
  return request;
 }

I suppose I could have gotten fancy and created a library that packages JSON-RPC more cleanly, but I chose to organize it as a collection of convenience methods. Here is the call from the parent code:

 RemoteCall remote = new RemoteCall();
 String response = null;
 try {
  response = remote.doPost();
 } catch (Exception e) {
  e.printStackTrace();
 }

Monday, May 9, 2011

Toggling Eclipse auto-suggest

The LogCat issue I described the other day caused a secondary problem: the auto-suggest feature in Eclipse was disabled! Well, to be fair I think I received a pop-up message about it, but who reads those anyway? So I accepted the message, and sadly, auto-suggest was gone.

To get it back, go to: Preferences > Java > Editor > Content Assist > Advanced. Make sure "Java Proposals" are enabled.

Friday, May 6, 2011

LogCat output is empty

I am using SpringSource Tool Suite which is a souped-up version of Eclipse (it comes with all kinds of plugins pre-installed as well as embedded servlet engines). The Android SDK comes with Log4J packaged, and the log output is shown in a window known as "LogCat". If this view isn't currently open, go to: Window > Show View > Other... > Android > LogCat

So.... For a few days, LogCat was producing output as expected. Then, it just went silent. Even restarting STS didn't bring back my beautiful logs. It turns out, whether coincidentally or otherwise, the MyLyn plugin causes some interaction as postulated in this post.

I did verify, on Mac OS X, that removing all JARs beginning with "org.eclipse.mylyn" causes LogCat to resume normally.

Thursday, May 5, 2011

Finding a Maven Repository

When you define a dependency in pom.xml, you are telling your compiler where to go get JARs from in the Maven archive. This way, you don't need to maintain your libraries and if they are updated, you simply change the version number in your pom.xml file.

If you know what dependency you need, for example, Apache Commons/IO, browse to a Maven mirror such as:
http://mirrors.ibiblio.org/pub/mirrors/maven2/
when you navigate down to:
http://mirrors.ibiblio.org/pub/mirrors/maven2/commons-io/commons-io/
The first and second directories represent the Group ID and the Artifact ID. For example:
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.0.1</version>
        </dependency>
In the above example, the reuse of "commons-io" makes it unclear, but the canonical form is:
http://mirrors.ibiblio.org/pub/mirrors/maven2/groupId/artifactId/