Friday, February 29, 2008

Autostarting services

Some privileged services start automatically in Android while the lowly applications I have written so far had to be started manually. I was not satisfied with the situation so I went after the Android bootup sequence.

The Linux layer under the JVM boots up normally, using the init script but I was not interested in that. I found that the Java services are all started by the System server (android.server.SystemServer) which does launch each system server in a hardwired way.

Log.i("SystemServer", "Starting Alarm Manager.");
sm.addService("alarm", new AlarmManagerService(context));
Log.i("SystemServer", "Starting Window Manager.");
wm = WindowManagerService.main(context, power);
sm.addService("window", wm);

There is no way getting our service autostarted this way but fortunately there is the android.intent.action.BOOT_COMPLETED intent which is broadcasted when the boot completes. One needs android.permission.RECEIVE_BOOT_COMPLETED permission to receive this intent.

Download the example program from here.

The example program has two parts: an intent receiver catching the BOOT_COMPLETED intent and a primitive service that counts down from 10 in every 3 seconds and logs the counter value. When it counts down, the service dies completely, this is necessary as there is no simple way to uninstall packages in the SDK so this service is not allowed to cause trouble later. Please, note the use of Handler for the timed countdown: you can't stay for too long in onStart() otherwise the application manager will shoot down the service.

Check the boot log below and you will find how the service is started. Each ... represents deleted log entries because meanwhile the boot process is happening and other services write the log.

D/BootCompletedIntentReceiver( 576): android.intent.action.BOOT_COMPLETED
D/BootCompletedIntentReceiver( 576): BackgroundService started
D/ActivityThread( 576): Creating service aexp.persistentapp.BackgroundService
D/BackgroundService( 576): onStart
I/ActivityManager( 510): Stopping service: {aexp.persistentapp/aexp.persistentapp.BackgroundService}
D/ActivityThread( 576): Stopping service aexp.persistentapp.BackgroundService@400bcb18
D/BackgroundService( 576): onDestroy
D/BackgroundService( 576): Counter: 10
D/BackgroundService( 576): Counter: 9
D/BackgroundService( 576): Counter: 8
D/BackgroundService( 576): Counter: 7
D/BackgroundService( 576): Counter: 6
D/BackgroundService( 576): Counter: 5


jav said...

How do you get access to the boot log?
I'm trying to find out, but I don't see how to actually get to it anywhere, just listings of what people have found inside the actual logs :)

THanks // Jav

Gabor Paller said...

From the console:
adb logcat
Many IDEs integrate the log access into their UIs.

jav said...

Any idea on how to see what belongs to the _previous_ boot? (if it is possible at all.).

My problem is that I'm trying to boot a custommade kernel, but it won't work for some reason, so I'd like to see what's happening. But it's a bit hard ;)

Anonymous said...

Thanks very very much!