Keep On Running…
Some may have noticed that I updated my previous post with a footnote describing an issue with my battery widget not resuming it’s updates after the phone went into (and came out of) deep sleep. I got to the bottom of that and can now happily report that my widget seems 100% reliable and the solution is not contributing to any additional battery drain.
This is what I did…
Specialised Services
I think I may have mentioned near the beginning of this series, that Services were a potentially complex area on Android. Even with this simple widget exercise I have learned quite a bit about them and still I think I have only scratched the surface.
I already refactored my code once to avoid using a deprecated method that I inadvertently adopted from an out of date example. I have now learned that for my needs, I should in fact be using a different Service class entirely!
Specifically, an IntentService.
The main difference between this and the Service class I was using previously, is that an IntentService does not run on the main application thread, but on it’s own worker thread, created by the system automatically when any intents are passed to it for handling.
Something led me to believe that an IntentService is “long lived” which, is the key to ensuring that my update schedule survived the device going into “deep sleep”.
To switch to an IntentService was relatively straightforward.
Update: Everything that follows is indeed how I switched to an IntentService. But it turns out this created a different problem which leads me to suspect that an IntentService does not function how I was led to believe and issn’t actually appropriate. Just bear that in mind.
First of all of course, I needed to derive from the IntentService class itself.
Then I again had to change the method being used to implement the service call. Previously I was using onStartCommand()
. This now needs to change to onHandleIntent()
.
There was one other change that I needed to make but I didn’t discover this until trying to install my updated widget. Had I read the guide to implementing services I would have known about it. But I hadn’t.
That other thing is that the service requires a parameterless constructor to be implemented. Why this is the case for an IntentService and not for a Service, I haven’t yet thought about. I am sure there is an explanation. But for now, all I need to know is that I need to implement such a constructor and it must call the inherited constructor that takes a service name as a parameter.
So first, the parameterless constructor:
constructor UpdateService; begin inherited constructor('UpdateService'); end;
Note that constructors are not named in Java. The token constructor, as opposed to the usual method declaration is all that we need. As I think I may have mentioned, you have the option of using Create (but only Create) to name your constructors if you wish (and this may be important for classes intended for cross-platform use) but in this case, I chose not.
The change of onStartCommand
to onHandleIntent
involves only changing the method signatures. The implementation is not affected at all:
method UpdateService.onHandleIntent(aIntent: Intent);
As far as I can tell, this deals with the issue of my widget updates surviving deep sleep, and importantly, without any adverse affect on battery drain that I have observed.
Update: This seems to be true, but is not actually functioning how I intended and so I shall revisit this change.
But there is something else that I haven’t yet taken care of (Update: which the IntentService had an adverse affect on – i.e. it broke it!), that I left a hint about in that previous post, and I shall be making that the subject of my truly final post in this series later this evening another post soon.
UPDATE
Take everything above with a pinch of salt.
In preparing the next post I discovered that things were not behaving quite as I thought and I need to do some more research before I can say definitively that I have found the correct approach for dealing with both the issue of surviving sleep and the subject of what was to be my next post.
Hey ho. It’s all learning, right ? 🙂
It’s fun to read about your progress here, Jolyon. It’s all learning, yes! And looks like you are enjoying it.
I have only done a little Android development with Java and really should learn more, but don’t seem to have the time for it, so this is all useful information. Although I won’t be using Oxygene (although I would probably love that as well), it is also nice to see what the RO guys have done in that front.