{"id":1869,"date":"2013-10-10T18:17:40","date_gmt":"2013-10-10T06:17:40","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=1869"},"modified":"2014-08-03T17:14:16","modified_gmt":"2014-08-03T05:14:16","slug":"developing-an-appwidget-part-4","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/1869\/","title":{"rendered":"Developing an AppWidget &#8211; Part 4"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><h2>Keep On Running&#8230;<\/h2>\n<p>Some may have noticed that I updated my <a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/1855\">previous post<\/a> with a footnote describing an issue with my battery widget not resuming it&#8217;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.<\/p>\n<p>This is what I did&#8230;<\/p>\n<p><!--more--><\/p>\n<h3>Specialised Services<\/h3>\n<p>I think I may have mentioned <a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/1791\">near the beginning of this series<\/a>, that <strong>Services<\/strong> 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.<\/p>\n<p>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 <strong>Service<\/strong> <strong>class<\/strong> entirely!<\/p>\n<p>Specifically, an <strong>IntentService<\/strong>.<\/p>\n<p>The main difference between this and the <strong>Service<\/strong> class I was using previously, is that an <strong><a href=\"http:\/\/developer.android.com\/reference\/android\/app\/IntentService.html\">IntentService<\/a><\/strong> does not run on the main application thread, but on it&#8217;s own worker thread, created by the system automatically when any intents are passed to it for handling.<\/p>\n<p>Something led me to believe that an IntentService is &#8220;<em>long lived<\/em>&#8221; which, is the key to ensuring that my update schedule survived the device going into &#8220;deep sleep&#8221;.<\/p>\n<p>To switch to an IntentService was relatively straightforward.<\/p>\n<p><em><strong>Update:<\/strong> Everything that follows is indeed how I switched to an <strong>IntentService<\/strong>.  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&#8217;t actually appropriate.  Just bear that in mind.<\/em><\/p>\n<p>First of all of course, I needed to derive from the <strong>IntentService<\/strong> class itself.<\/p>\n<p>Then I again had to change the method being used to implement the service call.  Previously I was using <code class=\"\" data-line=\"\">onStartCommand()<\/code>.  This now needs to change to <code class=\"\" data-line=\"\">onHandleIntent()<\/code>.<\/p>\n<p>There was one other change that I needed to make but I didn&#8217;t discover this until trying to install my updated widget.  Had I read the <a href=\"http:\/\/developer.android.com\/guide\/components\/services.html\">guide to implementing services<\/a> I would have known about it.  But I hadn&#8217;t.<\/p>\n<p>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&#8217;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.<\/p>\n<p>So first, the parameterless constructor:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  constructor UpdateService;\r\n  begin\r\n    inherited constructor('UpdateService');\r\n  end;\r\n<\/pre>\n<p>Note that constructors are not named in Java.  The token <strong>constructor<\/strong>, as opposed to the usual <strong>method<\/strong> declaration is all that we need.  As I think I may have mentioned, you have the option of using <strong>Create<\/strong> (but <em>only<\/em> 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.<\/p>\n<p>The change of <code class=\"\" data-line=\"\">onStartCommand<\/code> to <code class=\"\" data-line=\"\">onHandleIntent<\/code> involves only changing the method signatures.  The implementation is not affected at all:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  method UpdateService.onHandleIntent(aIntent: Intent);\r\n<\/pre>\n<p>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.<\/p>\n<p><em><strong>Update:<\/strong> This seems to be true, but is not actually functioning how I intended and so I shall revisit this change.<\/em><\/p>\n<p>But there is something else that I haven&#8217;t yet taken care of (<em><strong>Update:<\/strong> which the IntentService had an adverse affect on &#8211; i.e. it broke it!<\/em>), that I left a hint about in that previous post, and I shall be making that the subject of <del>my truly final post in this series later this evening<\/del> another post soon.<\/p>\n<h2>UPDATE<\/h2>\n<p><strong>Take everything above with a pinch of salt.<\/strong><\/p>\n<p>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.<\/p>\n<p>Hey ho.  It&#8217;s all learning, right ?  \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span>Keep On Running&#8230; Some may have noticed that I updated my previous post with a footnote describing an issue with my battery widget not resuming it&#8217;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% [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[212,205,4,180],"tags":[153,233,181,232],"class_list":["post-1869","post","type-post","status-publish","format-standard","hentry","category-android-2","category-cooper","category-delphi","category-oxygene","tag-android","tag-intentservice","tag-oxygene-2","tag-services"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-u9","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1869","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=1869"}],"version-history":[{"count":6,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1869\/revisions"}],"predecessor-version":[{"id":2238,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1869\/revisions\/2238"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=1869"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=1869"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=1869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}