Post navigation

Android Services: Recommendations when using AIDL for continuous service and low current drain impact

Last month a lot things happened.. I lost my dad, moved to another location .. thus, this blog was not the priority but was not forgotten.

This post is related to some issues I have observed in some Dalvik implementation and some recommendations is you want to create a service that must remains running all the time even after a device power on/off or reset.

3) is used to monitor something every X minutes but cannot impact the current drain.

4) the service must use the “uptime”, I mean, must reports “how long” is running

5) must be able to receive interruptions and reports them

A good application of this service could be an alarm central unit for your car. You could create this project using your old Android phone and transforming your old phone and hidden it in your car. You can also connect this old phone disassembling a 12V charging and connecting in some spot using the terminals of your battery.

If you are an old J2ME programmer probably the first option you can have in your mind to track your “uptime” is the System.currentTimeMillis(). However, if the user change the time/date the System.currentTimeMillis() is impacted!

The correct option on this case, is the SystemClock.elapsedRealtime() that will bring to you the total milliseconds after boot and it is not impacted with date/time.

Mistake 2) Wrong UPTIME

In the Mistake 1, you realized the importance of SystemClock.elapsedRealtime() but if your service need to auto-start when the devices boot, you should register the intent BOOT_COMPLETE.

So, it is very common to see developers using the UPTIME using directly the SystemClock.elapsedRealtime(), but remember! It is not only your service that starts after boot and of course, if UPTIME is something that must be precise your need to reduce the time waste to start your service.

I now, sounds ridiculous but it is very common mistake in real time systems.

Mistake 3) Using wakelocks instead RTC Alarms

If your system cannot be invasive, avoid the consume of the battery, but your need to monitor some inputs periodically, wakelocks is really the worst because will prevent your phone to sleep consuming a high current all the time. The best option on this case is to use the RTC of your device to wake up your service.

This is very tricky… there are situation that your system may be affect by “low memory”event, and the Dalvik decides to kill everything not in use including the background processes. Sometimes you will be able to the in logcat messages like “Too many background processes”, “Low memory”, and believe it is something you cannot control due to many variables in your device (sometimes many horrible software implementations installed in your system too).

When the Dalvik kills the services, as son we have decent memory available the Dalvik tried to restart everything again. Then you have a great surprise! Even you using a AIDL service, your client was not able to receive the UNBIND event, even a “service disconnect” error, and you are completely lost.

Why ? Well.. I tell a specific situation that I could realize some Dalvik implementation failing.

Suppose your service was using a periodically RTC event (like described on Mistake 3 previously) and then your service contains a receiver like the line:

Intent intent = new Intent(receiver.ACTION_REFRESH_SCHEDULE_ALARM);

Then, just after Dalvik killed you service, the RTC generates an event. Even your service already killed, the receiver will receive the intent. On this case, if you are accessing something already destroyed with your service, for example, an object that makes reference some memory in native side (NDK implementation) or your parcelable object are null at this time, your service will not be RESTARTED !!!

This is scenario that I could realize some implementation are failing. How to fix this issue ?

and be precocious that in your receiver make sure the objects you are accessing are not null.

If you do this, the Dalvik will be able to re-start the service without problem.

Mistake 5) Saving all the time your data

If you need to save data, be reasonable.. Sometimes it is better to save in cache (RAM) and in specific amount of time save it. If you have summarized info to be save and the data is very few, try to use a light mechanism.. For example, SharedPreferences is lighter than SQL Lite on this situation.

Mistake 6) Problem with exceptions and tombstones

If your system access external devices and you have special NDK implementation on your system, make sure you are not masking any problem on your native side. For example: