Correcting an AnDevCon Presentation

Here are some clarifications on some points of contention from a presentation I just attended at AnDevCon.

Using android:process

The presenter stated that developers always should use android:process when writing services. The rationale — not included in the presentation but elaborated upon in post-presentation discussion — appears to be based upon this paragraph from the Android developer documentation:

In addition, a process’s ranking might be increased because other processes are dependent on it—a process that is serving another process can never be ranked lower than the process it is serving. For example, if a content provider in process A is serving a client in process B, or if a service in process A is bound to a component in process B, process A is always considered at least as important as process B.

The presenter’s argument, therefore, is that a service needs to go in its own process, so that activities that have been moved to the background do not drag down the priority of the process, causing it to be terminated prematurely.

This, however, runs counter to the preceding paragraph:

Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process is ranked as a visible process, not a service process.

and the subsequent paragraph:

Because a process running a service is ranked higher than a process with background activities, an activity that initiates a long-running operation might do well to start a service for that operation, rather than simply create a worker thread—particularly if the operation will likely outlast the activity. For example, an activity that’s uploading a picture to a web site should start a service to perform the upload so that the upload can continue in the background even if the user leaves the activity. Using a service guarantees that the operation will have at least “service process” priority, regardless of what happens to the activity. This is the same reason that broadcast receivers should employ services rather than simply put time-consuming operations in a thread.

Hence, background activities will not cause a service process to somehow fall in priority, so there is no reason to fork another service just to help keep the service’s process priority higher.

Furthermore, core Android team members have stated that developers typically have no need to use android:process. It ties up another VM’s worth of RAM for little added value.

Using com.android.vending

The presenter suggested that developers use a particular Intent broadcast by the Android Market app (com.android.vending) to get control when their app is installed.

When I pointed out that this is not part of the Android SDK, he indicated that “that’s why it’s cool” and suggested that Google staff told his employer it was OK to use.

IMHO, “that’s why it’s cool” is not a valid justification for advising people to use code that core Android team members have indicated will cause their apps to break in the future. Anything in com.android is not part of the Android SDK and is subject to change without warning.

This isn’t completely the presenter’s fault — I have seen this broadcast suggested by, of all people, the Google Analytics folk. I do wish that Google would keep their story straight internally. For the moment, I am sticking by the “this broadcast is not part of the SDK” argument, as it remains consistent with Google’s position regarding other com.android things people try to use.

Polling by Handler

The presenter showed a code sample demonstrating a service that implemented an internal polling mechansism using a Handler and postDelayed(). This suggestion, while not inconceivable, does come with some caveats that the presenter perhaps did not have time to cover:

  • The work being done via the Runnable passed to postDelayed will be performed on the main application thread. That’s possibly still safe for within a service, but services typically are involved in more complex processing that would take too long to perform safely on the main application thread.

  • This model encourages the creation of “everlasting services”, particularly of the variety that just ties up RAM all day watching the clock tick.

A better solution for most cases — covered later in the presentation — is AlarmManager, so the “watch the clock tick” portion is handled by the operating system, so the service can get out of RAM (the presenter’s “short-lived services”) model.

There may be scenarios where polling-by-Handler is appropriate for a service (e.g., polling frequency too fast for AlarmManager to be practical), but I strongly suspect they are outliers, not the norm.

AIDL

The presenter illustrated binding to a service via AIDL. This, of course, is a perfectly valid technique… for certain situations. The problem lies in the presenter’s depiction of using this for services within your application.

This is perhaps an outgrowth of the android:process issue outlined above. In that case, you would need the complexity of AIDL, which is designed for inter-process communication. However, services local to an app should be in the same process as the activities and the rest of the app. In that case, the local binding pattern (having the onBind() method return an instance of a developer-defined subclass of Binder) is typically simpler.

AIDL, however, is very appropriate for exposing a service API to third-party applications, a point which I believe the presenter did mention.

BroadcastReceiver and Device Wakeup

An audience member asked what causes the Android device to wake up, besides AlarmManager. What will wake up the device, we have been told, include:

  • AlarmManager
  • Incoming phone calls
  • Incoming text messages
  • Incoming packets on an established socket over a mobile data connection (e.g., 3G)

The latter is used by C2DM, which the presenter did a nice job of introducing.

I am not aware of anything else that will wake up the device, beyond the user pressing the power button.